总结一下:
1、类加载(初始化) 包括加载(类的class文件读入内存,并为之创建一个java.lang.Class对象,由类加载器完成)、连接(把类的二进制数据合并到JRE中)、初始化(对静态属性进行初始化) 三个步骤
2、什么时候会 进行 类加载(初始化)
(1)创建类的实例:包括用new、反射、反序列化来创建 (反序列化时候——构造器不会被调用,类似于赋值也不会被调用)
(2)调用某个类的静态方法
(3)访问某个类或接口的静态属性,或为该静态属性赋值 (final类型的静态属性,如果它的值在编译时就可以得到,系统使用时会认为是对该类的被动使用,所以不会导致该类的初始化)
(4)使用反射来强制创建某个类或接口对应的java.lang.Class对象。例如,代码Class.forName("Person") (或者:Person.class),如果系统还未初始化Person类,则这行代码会导致该Person类被初始化,并返回Person类对应的java.lang.Class对象
(5)初始化某个类的子类
(6)直接使用java.exe来运行某个主类,当运行某个主类时,程序会先初始化该主类
(7)直接使用类加载器来加载类——当使用ClassLoader类的loadClass()方法加载某个类时,该方法只是加载该类,并不会执行该类的初始化
3、获取 某个类或接口对应的java.lang.Class对象 的方法
(1)上述的第(4)点里——Person.class
(2)上述的第(4)点里——Class.forName("Person")
(3)Person person = new Person(); person .getClass();
(4)上述第(7)点, //运行main方法的时候,ReflectTest主类已经被加载,这时候可以用ReflectTest的类加载器来加载其他类
Class<?> clazzD = ReflectTest.class.getClassLoader().loadClass("wxtest.D");
例:
1 package wxtest; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 import sun.security.jca.GetInstance.Instance; 7 8 9 public class ReflectTest { 10 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException { 11 Class<?> clazzA = A.class; 12 System.out.println(clazzA); 13 14 Class<?> clazzB = Class.forName("wxtest.B"); //会初始化静态化块 15 System.out.println(clazzB); 16 17 C c = new C(); //会初始化静态化块 18 System.out.println("new C()结束"); 19 Class<?> clazzC = c.getClass(); 20 21 22 //运行main方法的时候,ReflectTest已经被加载,这时候可以用ReflectTest的类加载器来加载其他类 23 Class<?> clazzD = ReflectTest.class.getClassLoader().loadClass("wxtest.D"); 24 System.out.println(clazzD); 25 26 27 Class<?> clazz1 = LcdTV.class; 28 System.out.println(clazz1); 29 30 Class<?> clazz2 = Class.forName("wxtest.LcdTV"); 31 System.out.println(clazz2); 32 33 LcdTV lcdTV = new LcdTV(); 34 Class<?> clazz3 = lcdTV.getClass(); 35 System.out.println(clazz3); 36 37 System.out.println("clazz1 equals clazz2 ? = " + clazz1.equals(clazz2)); 38 System.out.println("clazz1 equals clazz3 ? = " + clazz1.equals(clazz3)); 39 40 Object instace = clazz3.newInstance(); //调用默认构造器 41 System.out.println("实例化好的对象为= " + instace); 42 43 //调用 public void turnOn() 44 Method method = clazz3.getMethod("turnOn", new Class<?>[]{}); 45 method.invoke(instace, new Object[]{}); //参数2是什么:调用方法的实参列表 */ 46 47 } 48 } 49 50 class A { 51 static { 52 System.out.println("A中的静态块初始化..."); 53 } 54 } 55 56 class B { 57 static { 58 System.out.println("B中的静态块初始化..."); 59 } 60 } 61 62 class C { 63 static { 64 System.out.println("C中的静态块初始化..."); 65 } 66 } 67 68 class D { 69 static { 70 System.out.println("D中的静态块初始化..."); 71 } 72 } 73 74 interface Televition { 75 void turnOn(); 76 void turnOff(); 77 } 78 79 //液晶电视 80 class LcdTV implements Televition { 81 82 private boolean on = false; 83 public final int size; //public final int size=0;会报错 84 static { 85 System.out.println("LcdTV静态代码块被初始化..."); 86 } 87 88 public LcdTV() { 89 size = 32; //The blank final field size may not have been initialized 90 } 91 92 public LcdTV(int size) { 93 this.size = size; 94 } 95 96 @Override 97 public void turnOn() { 98 System.out.println(size + "寸 电视被打开"); 99 on = true; 100 } 101 102 @Override 103 public void turnOff() { 104 System.out.println(size + "寸 电视被关闭"); 105 on = false; 106 } 107 }
结果为:
C中的静态块初始化... new C()结束 class wxtest.D class wxtest.LcdTV LcdTV静态代码块被初始化... class wxtest.LcdTV class wxtest.LcdTV clazz1 equals clazz2 ? = true clazz1 equals clazz3 ? = true 实例化好的对象为= wxtest.LcdTV@70f9f9d8 32寸 电视被打开
参考:
http://www.ibm.com/developerworks/cn/java/j-lo-classloader/
http://blog.csdn.net/xyang81/article/details/7292380