JAVA类的加载(5)——总结

总结一下:
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 }
View Code

结果为:

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

posted on 2013-11-19 11:46  gogoy  阅读(277)  评论(0编辑  收藏  举报

导航