在Java代码中,类型(什么是类型?Class,接口,枚举,但不涉及对象概念)的加载、连接与初始化过程都是:在程序运行期间完成,在程序运行期间完成,在程序运行期间完成,提供了更大的灵活性,增加了更多的可能性。
类型的加载最常见的是:将已经存在的class文件从磁盘上加载到内存里。
假如类里面有一个static int a = 5 ; 那么准备阶段是给这个 a 的默认值分配 0.
至于 a = 5是在初始化阶段才赋值的。初始化阶段是为类的静态变量赋予正确的初始值。
假如已经编译好了class文件,手动打开记事本修改了里面的内容。那么类是不能正常加载的,验证阶段就是去检查这部分内容的。
注意,不会导致类的初始化。类的初始化是为静态变量进行赋值。
代码:
根据主动使用原则:
说白了就是主动使用的7个原则,都会导致类的初始化,
虽然没有执行son类的静态代码块,但是son类加载了,但是还没有初始化。这个控制台需要在配置
注意 主函数所在的类也被加载了,并且初始化了,因为这个demo类执行了main方法,而
再看一个代码:
可以看到并没有执行Person类的静态代码块。
这个问题的原因是:在编译阶段,常量就会被存入到调用这个常量的方法所在的类的常量池当中。 也就是说:这个常量会被存入到MyTest类的常量池当中。存入之后,这两个类就没关系了,删除了Person的class文件也没事。
本质上:调用类并没有直接引用到定义常量的类,因此并不会触发定义常量的类的初始化,也就不会执行Person类的静态代码块了。
因为这些常量都是LDC iconst bipush sipush 类操作的 所以跟Person类就没关系了。
这样的情况下,静态代码块又执行了,这是因为:
当一个常量的值并非编译器可以确定的,那么其值就不会被放到调用类的常量池中,这时在程序运行期间,会导致 “主动使用” 这个常量所在的类,显然会导致这个类被初始化
当一个接口初始化时,并不要求其父接口都完成了初始化。只有在真正使用到父接口的时候(如引用接口中所定义的常量时),才会初始化。
双亲委派模型的工作流程是:如果一个类加载器收到一个类加载请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类容器中。只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
而使用双亲委派模型来组织类加载器之间的关系,有一个显而易见的好处就是Java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如Object类,他存放在 rt.jar 中,无论哪一个类加载器要加载这个类,最终都委派给处于模型最顶端的启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。
相反,如果没有使用双亲委派模型来组织类加载器之间的关系,由各个类加载器自行去加载的话,如果用户编写了一个Object类,并且放在程序的Classpath中,那系统将会出现多个不同的Object类,那么Java类型体系中最基础的行为也就无法保证,应用程序也会将变得一片混乱
网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。
添加我为好友,拉您入交流群!
请使用微信扫一扫!