java Class被加载的时机
2016-12-29 10:29
405 查看
简单概括:当主动使用此类时,就会被加载,分为以下6种情况:
1.创建类的实例
2.访问某个类或者接口的静态变量,或者对该静态变量赋值
3.调用类的静态方法
4.反射(Class.forName())
5.初始化类的子类
6.java虚拟机启动时的main方法所在类
下面用代码来举例:
首先要明白的是,类被加载判断:类中的静态代码块会执行。
实例一:
实例二:
实例三:
实例四:
最后来一个奇怪的实例
很多人可能会猜到肯定是打印 1,1 啊 ,都不用想啊,实际并非如此!应该是1,0
分析: 首先编译期间,各静态变量都声明了,等号右边的这时都还不用管。然后加载Target类时 ,静态从上往下看,static final Target会导致构造执行,a和b 都加1 ,此时a和b都是1 ,然后 到b时,主动又赋值为0 ,所以b会从1变到0,而a不变。
如果将Target变成这样
谢谢大家,完毕!来句闲话,深圳有爱好音乐的会打鼓的程序员可以一起交流加入我们乐队一起嗨。我的QQ:657455400
1.创建类的实例
2.访问某个类或者接口的静态变量,或者对该静态变量赋值
3.调用类的静态方法
4.反射(Class.forName())
5.初始化类的子类
6.java虚拟机启动时的main方法所在类
下面用代码来举例:
首先要明白的是,类被加载判断:类中的静态代码块会执行。
实例一:
public class ClassLoaderTest { public static void main(String[] args){ //加了final后编译期确定,所以不会加载Target类 System.out.println(Target.x); } } class Target { public static final int x = 6 / 3 ; static { System.out.println("Target类被加载了"); } } // 结果 : 2
实例二:
public class ClassLoaderTest { public static void main(String[] args){ //会加载Target类 System.out.println(Target.x); } } class Target { public static int x = 6 / 3 ; static { System.out.println("Target类被加载了"); } } // 结果 : Target类被加载了 2
实例三:
public class ClassLoaderTest { public static void main(String[] args){ //都是使用父类的 ,不会加载子类Target类 System.out.println(Target.x); Target.p(); } } class Parent{ static int x = 0; static void p(){ } } class Target { static { System.out.println("Target类被加载了"); } } //结果 0
实例四:
public class ClassLoaderTest { public static void main(String[] args){ // 获得应用类加载器 ClassLoader appLoader = ClassLoaderTest.class.getClassLoader().getSystemClassLoader(); Class tClazz = appLoader.loadClass("Target");//这里不会导致Target类被加载,只是加载文件成二进制 System.out.println("loadClass"); tClazz.newInstance(); // 这里就会导致Target被加载 } } class Target { static { System.out.println("Target类被加载了"); } } // 结果 : loadClass Target类被加载了
最后来一个奇怪的实例
public class ClassLoaderTest { public static void main(String[] args){ Target.getInstance(); System.out.println(Target.a + ","+Target.b); } } class Target { private static final Target t = new Target(); static int a ; static int b = 0; private Target(){ a++; b++; } public static Target getInstance(){ return t ; } } //这里大家猜下结果会是神马? A 1,0 B 0,1 C 0,0 D 1,1
很多人可能会猜到肯定是打印 1,1 啊 ,都不用想啊,实际并非如此!应该是1,0
分析: 首先编译期间,各静态变量都声明了,等号右边的这时都还不用管。然后加载Target类时 ,静态从上往下看,static final Target会导致构造执行,a和b 都加1 ,此时a和b都是1 ,然后 到b时,主动又赋值为0 ,所以b会从1变到0,而a不变。
如果将Target变成这样
class Target { static int a ; static int b = 0; private static final Target t = new Target(); private Target(){ a++; b++; } public static Target getInstance(){ return t ; } } // 结果 1 , 1
谢谢大家,完毕!来句闲话,深圳有爱好音乐的会打鼓的程序员可以一起交流加入我们乐队一起嗨。我的QQ:657455400
相关文章推荐
- java Class 的加载时机
- 在Java中动态加载class
- java中动态加载类 Class.forName
- Java Class的热替换 自定义ClassLoader加载.class
- Java 类加载体系与ContextClassLoader
- javac编译成功,用java运行class文件出现“找不到或无法加载主类”
- 无需定义类路径加载JAVA CLASS
- Java的Class对象的加载和初始化
- python 动态加载类,类似java的class.forName
- Java--对于 class文件进行加密 然后通过我们自己写的类加载器进行加载指定类
- java 的类加载机制(classloader)
- Java获得指定ClassLoader所加载的类列表
- java代码实现利用 classloader 动态加载 jar包、文件夹到classpath中
- 类的加载器 java.lang.ClassLoader
- JAVA学习之JVM加载class
- 在Eclipse中配置动态加载Class的JVM插件--JavaRebel
- java class 是如何加载的
- 文件中加载jar及Class,启动Java(Windows及Linux)
- JAVA类的静态加载和动态加载以及NoClassDefFoundError和ClassNotFoundException
- 每天一到面试题 - 5 - Java - ClassLoader如何加载class