Java SE 学习笔记 第十六记

1、Dom4J的document.asXML();将document的XML文档转换为字符串。


2、InputStream的read方法在输入数据可用,或者检测到流末尾以及抛出异常之前,read方法一直处于阻塞状态。


3、Java虚拟机:当应用程序执行的时候会先创建一个JVM虚拟机进程以及一个主线程来执行应用程序。


4、Java虚拟机结束生命周期的情况:
1)执行了System.exit()方法,参数为0时表示正常结束,否则为非正常结束。
2)应用程序正常执行结束。
3)应用程序在执行过程中遇到了异常或者错误而终止,JVM也会终止。
4)由于操作系统出现错误而导致Java虚拟机进程终止。


5、JVM装载类的过程:
1)加载:查找并加载应用程序的类的二进制数据,也就是类的class文件。
2)连接:
——验证:检查确保加载的类的正确性,保证类符合JVM虚拟机运行数据结构规范。
——准备:为类的静态变量分配内存,并将它们初始化为默认值。
——解析:把类中的符号引用转换为直接引用。
3)初始化:按照类文件中上下顺序为类的静态变量赋予用户设计类静态变量的正确初始值。
比如:public static int a = 1;在装载时,实际上是在连接准备阶段先赋给a值0,之后在初始化阶段再赋给a值1.


6、Java程序对类的使用分两种方式:主动使用和被动使用。


7、Java虚拟机在每个类或者接口被Java程序首次主动使用的时候才会初始化它们。除了主动使用的情况之外,Java都不会对使用的类做初始化。


8、Java程序对类主动使用的六种情况:
1)new,创建了类的实例。
2)访问了某个类或者接口的静态变量,或者对静态变量赋值。
3)调用了类的静态方法。
4)使用反射机制。
5)初始化一个类的子类时,父类也会被初始化。
6)Java虚拟机启动时被标明为启动类的类,也就是一个java源文件中与源文件相同名字的类。


9、类加载本质:类的加载是将类的class文件中的二进制数据读入到内存中,放置到运行时的数据区的方法区内,然后在堆区创建一个java.lang.Class对象用来封装这个类在方法区内的数据接口,并提供了访问方法去内数据结构的接口(反射机制就是通过这些接口进行反射),类Class对象反映描述了类的内容。因此,每一个类无论有多少个对象都只有一个对应的Class对象,并且每个类的Class对象只能由JVM自己在加载class文件时创建。


10、Java虚拟机支持加载class的方式:
1)从本地系统中直接将class加载
2)通过网络下载class文件
3)从zip或者jar等归档文件中加载
4)从专有数据库中提取class文件
5)从java源文件动态编译为class文件。


11、类加载器:
1)Java虚拟机自带加载器:
a)根类加载器(Bootstrap):使用C++编写,程序员无法获得该类对象。
b)扩展类加载器(Extension):Java编写。
c)系统类加载器(System):也叫应用加载器,Java编写。
2)用户自定义类加载器:继承抽象类java.lang.ClassLoader,用户可以定制类的加载方式。


12、Class类的方法getClassLoader()方法可获得该Class对象的类加载器,当该Class对象的加载器为根类加载器时,返回值为null,因为Java不允许用户访问根类加载器。


13、JVM允许类加载器在预料到某个类将要被使用的时候就预先加载这个类,与类初始化必须等到该类被首次主动使用不同。如果在预先加载的过程中遇到了class文件缺失或者存在错误,类加载器要报告LinkageError错误必须等到这个类被首次主动使用的时候才报告,要是这个类一直没有被程序主动使用,那么类加载器就一直不报告错误。


14、类的连接就是将已经读入到内存的类的二进制数据合并到虚拟机运行时环境中。


15、类连接阶段的验证内容:
1)类文件的结构检查:确保类文件遵从Java类文件的固定格式。
2)语义检查:确保类本身符合Java语言的语法规定,比如验证final类型的类有没有子类等。
3)字节码验证:确保字节码流可以被Java虚拟机安全执行。字节码流代表Java方法(包括静态方法和实例方法),它是由被称作操作码的单字节指令组成的序列,每个操作码后都跟着一个或多个操作数。字节码验证步骤会检查每个操作码是否合法,即是否有着合法的操作数。
4)二进制的兼容验证:确保互相应用的类之间协调一致。比如worker类要调用Car类的run方法,Java虚拟机就会验证方法区内是否存在Car类的run方法,如果不存在就会抛出NoSuchMethodError错误。又比如当JDK版本由1.6转为1.5时,程序也可能二进制验证不通过。


16、类连接阶段的准备:Java虚拟机为类的静态变量分配内存,并设置默认的初始值,对象静态成员变量的默认值为null。


17、类连接阶段的解析:Java虚拟机把类的二进制数据中的符号引用替换为直接引用。比如Worker类调用Car类方法run,在Worker类的二进制数据中就存在一个run方法的符号引用,这个引用由run方法的全名和相关描述符组成,而解析阶段就是把这个符号引用替换为Car的run方法在方法区的内存位置,这个内存位置就是直接引用。


18、类的初始化阶段:Java虚拟机执行类的初始化语句,为类的静态变量赋予初始值。静态变量的初始化有两种途径:一是在静态变量声明时进行初始化;二是在静态代码块中进行初始化。类的初始化过程按照程序中初始化语句的先后顺序初始化。


19、类的初始化步骤:
1)假如这个类还没有被加载和连接,就会先进行类的加载和连接。
2)假如类存在直接父类,并且这个父类还没有被初始化,那么就会先对父类进行初始化后再初始化子类。
3)假如类中存在初始化语句,那么依次执行这些初始化语句。


20、一个类的变量使用static final修饰,那么它是一个静态常量。如果静态常量的值在编译时就能够确定(如具体数值或者数学表达式),则即使是首次主动使用这个静态常量也不会导致类的初始化;相反,如果静态常量的值需要在运行时才能确定(比如常量值需要new一个对象),那么首次主动使用这个静态常量时会导致类的初始化。


21、子类初始化的时候不会导致父接口的初始化,接口的初始化只有在首次主动使用接口的静态变量时才会导致接口的初始化。


22、加载一个程序时,最先初始化的是启动标志类。


23、同一个类加载器加载一个类后不会再对这个类二次加载,但不同的类加载器可以对同一个类加载。


24、程序首次主动使用静态变量或者静态方法会进行初始化的前提是主动使用的静态变量或静态方法必须定义在当前的类或者接口中,比如首次主动使用子类的中定义在父类里的静态变量或者静态方法,子类不会被初始化,但父类会初始化。


25、二进制名称:指的是一个类名的全称,包括包名和类名,内部类和匿名内部类的二进制名称中带有$字符,也就是说有效类的二进制名称实际上就是该类编译后生成的class文件的文件名(除去.class),这种命名方法是Java Language Sepcification规范定义的。

你可能感兴趣的:(java,jvm,虚拟机,Class,类加载)