合格的java程序员,需要掌握java se中70%的类,也就是2800个类的熟练使用
jvm运行字节码程序的过程?程序是如何运行的?
一个类若想运行,则该类中一定包含主方法public static void main(String [] args){}
我们知道这是程序运行的入口,那么为什么只有这个才是程序运行的入口呢?
java程序运行:字节码文件经过解释器的解释运行在jvm虚拟机器上,jvm虚拟机需要找到程序运行的入口,解释器规定程序运行的入口是public static void main(String[] args){},即jvm虚拟机的解释程序在运行程序时,需要找到解释的入口才能让程序得以运行,
jvm通过解释器加载含有public static void main(String[] args){}方法的类,jvm负责执行此方法,因此为public,声明为static是因为jvm加载该类时并不会主动创建该类的对象,jvm通过该类来调用主方法,void无返回值,返回给jvm,参数string[] args是负责jvm如果想给此方法传参的接口
在jvm成功调用主方法后,程序得以运行,在运行的过程中,程序还是会加载类到内存中,如果需要创建对象,程序会为该对象分配堆内存,为一些方法中的局部变量分配栈内存,程序继续运行
获取文件/输入流中的数据的类Scanner?
那么在程序运行过程中如何获取文件/输入流中的数据的呢?
java为我们提供了一个类Scanner:用于在程序运行过程中获取外部数据
Scanner类是一个文本扫描器类,这个类可以扫描文件/输入流/字符串中的文本,解析出基本类型值和字符串值
1扫描输入流-----------Scanner获取键盘输入/标准输入
Scanner sc=new Scanner(System.in);//将输入流作为构造器的参数,System类直接调用其类变量输入流static InputStream in
Scanner提供的两个实例方法用于扫描标准输入
hasNextInt()/hasNext():判断是否还有下一个输入项(int/long/string)
nextXxx():获取下一个输入项默认情况下,
Scanner使用回车/空格/Tab作为输入项之间的间隔,默认使用的是空格作为输入项之间的间隔 sc.useDelimeter("\n");
2扫描文件--------------Scanner获取文件输入
Scanner sc=new Scanner(new File("xx.txt"));//将文件对象作为构造器参数
代表当前java程序运行平台的类System?
system类是对当前java程序运行平台的一个抽象的类,提供了访问运行平台的方法。
1不允许System类创建实例,否则就会有很多的java程序运行平台,
因此System类中只有类变量和类方法,因此平日我们也是直接通过System类来调用的类变量
public final class System {
private static native void registerNatives();
static {
registerNatives();
}
private System() {//构造器私有,只允许本类创建system的实例
}
public final static InputStream in = null;//system类变量:标准输入流
public final static PrintStream out = null;//system类变量:标准输出流
public final static PrintStream err = null;//system类变量:错误输出流
}
2java无法访问操作系统底层硬件设备,必须借助c语言来实现,因此native方法使用c语言来为java方法提供实现
实现步骤如下
(1)声明native方法,只有方法签名,没有方法实现,编译得到class文件
(2)javah 编译第一步生成的class文件,产生一个.h文件
(3)写一个.cpp文件实现native方法
(4)将.cpp文件编译成动态链接库文件
(5)在java中用System类的loadLibrary()方法/Runtime类的loadLibrary()放啊加载动态链接库文件,在java程序中就可以调用这个native方法了
3System提供了访问运行平台属性的方法。
getProperties()/getenv()/getProperty()访问当前java程序运行平台的系统属性和环境变量
public static Properties getProperties() {
SecurityManager sm = getSecurityManager();
if (sm != null) {
sm.checkPropertiesAccess();
}
return props;
}
4System还提供调用了辅助当前平台进行垃圾回收和进行资源清理的线程的执行的方法
public static void gc() {
Runtime.getRuntime().gc();
}
public static void runFinalization() {
Runtime.getRuntime().runFinalization();
}
5System类还提供了获取当前运行平台的时间的方法
public static native long currentTimeMillis();
public static native long nanoTime();
代表java程序的运行环境Runntime类?
每一个java程序都有与之对应的Runtime实例,An application cannot create its own instance of this class.
可以通过Runtime类访问JVM的相关信息,处理器数量/内存信息
public class Runtime {
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime() {//外部程序访问当前运行环境实例的接口
return currentRuntime;
}
private Runtime() {}//不允许外部程序创建Runntime实例
public native long freeMemory();//jvm的空闲内存
public native long totalMemory();
public native long maxMemory();
public native void gc();//系统垃圾回收的方法实现由c完成
private static native void runFinalization0();//清理系统资源的方法由c完成
public void exit(int status) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(status);
}
Shutdown.exit(status);
}
public void loadLibrary(String libname) {//提供这些方法来加载文件和动态链接库
loadLibrary0(Reflection.getCallerClass(), libname);
}
public void load(String filename) {
load0(Reflection.getCallerClass(), filename);
}
}
所有类的父类?Object
Object是所有类,数组,枚举类的间接父类,当定义类时,如果没有显示extends,则该类默认继承Object类
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();//返回该对象运行时的类对象
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;//实现自我克隆
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
protected void finalize() throws Throwable { }//由垃圾回收器调用
}
任何类都是Object类的子类,因此子类实例可以调用/重写Object类的实例方法
又发现了一个标记接口--Cloneable,实现该接口的类的实例可以实行按自我克隆
public interface Cloneable {
}
自定义类实现克隆的方法
实现自己的clone方法,通过super.clone();得到该对象的副本,并返回该副本、、
public User clone(){
return (User)super.clone();
}
但是Object类方法实现的clone()都是浅克隆,即只会克隆对象的所有成员变量的值,并不会对引用类型变量的成员变量的值引用的独享进行克隆,克隆的只是地址值,开发者需要自己深克隆
操作对象的工具类Objects?
public final class Objects {
private Objects() {
throw new AssertionError("No java.util.Objects instances for you!");
}
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
public static String toString(Object o) {
return String.valueOf(o);
}
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
public static boolean isNull(Object obj) {
return obj == null;
}
public static boolean nonNull(Object obj) {
return obj != null;
}
}
这些工具方法大多是空指针安全的