类加载机制与反射

Posted wheleetcode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类加载机制与反射相关的知识,希望对你有一定的参考价值。

1 系统可能在使用某个类时加载该类,也可能采用预加载机制加载某个类。

2 当调用Java命令运行Java程序时,命令会启动一个Java虚拟机进程

3  当系统主动使用某个类时,如果类还没有被加载到内存,系统会通过加载,连接,初始化来对类进行初始化,类加载是指将类的class文件读入内存,并创建一个class对象。

4 类的连接:生成一个class对象后,进入连接阶段,负责把二进制数据合并到jre中

1 验证 :检验类是否有正确的内部结构  2 准备:为类的静态field分配内存,设置默认初值  3 解析:将二进制数据中的符号引用变成直接引用

5 类的初始化 : 主要对静态field进行初始化 1 声明静态field时指定初值 ,2 使用静态初始化块

类初始化时机   1 创建类实例  new  反射创建  反序列化创建  2 调用类的静态方法  3 访问类或接口静态field  或为静态field复制  4 反射创建类的class对象 Class.forName(),  5 使用java命令运行某个主类 

  final型的静态field,如果field值在编译时确定,相当于宏变量,编译器会在编译时把field出现的地方替换成他的值,不会导致类初始化。

classLoader类loadclass方法加载某个类时,只加载类,不会初始化类

技术分享
public class JDBCTest extends Thread{
    public static void main(String[] args) throws ClassNotFoundException {
//        System.out.println(A.a);
//        System.out.println(A.b);
         ClassLoader c = ClassLoader.getSystemClassLoader();
        c.loadClass("com.whe.db.A");
    }
}

class A {
    public final static int a = 0;
    public final static int b = new Random().nextInt(10);
    static{
        System.out.println("chu shi hua");
    }
}
View Code

6 Java中的类使用包名类名做唯一标识  jvm使用包名,类名,加载器名做唯一标识。根类:加载核心类库 String  system  扩展 : jre/lib/ext    extension   3  系统: -classpath   java.class.path 属性  

 7 类加载机制  1 全盘负责:当一个类加载器负责加载某个class时,该class所依赖和引用的其他class也将由该类加载器载入   2 父类委托 先让父类加载器试图加载该class , 只有在父类加载器无法加载时,才尝试从自己类路径加载该类。3 缓存 机制 , 保证所有加载过的class都会被缓存,缓存不存在时才读取类的二进制数据,并转换成class对象,放入缓存区

技术分享
file:/D:/andro/Test/bin/
D:\program\1.7\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
public class JDBCTest extends Thread{
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        ClassLoader c = ClassLoader.getSystemClassLoader();
        Enumeration<URL> e = c.getResources("");
        while (e.hasMoreElements()) {
            System.out.println(e.nextElement());
        }
        ClassLoader cp = c.getParent();
        System.out.println(System.getProperty("java.ext.dirs"));
    }
}
View Code

8 获取class对象

        Class a = Class.forName("com.whe.db.A");
        Class b = A.class;    比较好,可以在编译时期获得,不会抛出异常
        A c = new A();
        Class d = c.getClass();

9 创建对象

技术分享
public class JDBCTest extends Thread{
    public static void main(String[] args) throws Exception {
        Class a = Class.forName("com.whe.db.A");
        Constructor c = a.getConstructor(String.class);
        c.newInstance("ds");
        a.newInstance();
    }
}

class A {
    public A() {
        System.out.println("con");
    }
    public A(String name) {
        System.out.println(name);
    }
}
View Code

10 调用方法

技术分享
public class JDBCTest extends Thread{
    public static void main(String[] args) throws Exception {
        Class a = Class.forName("com.whe.db.A");
        A b = (A) a.newInstance();
        Method m =a.getDeclaredMethod("info", String.class);
        m.setAccessible(true);
        m.invoke(b, "i am jory");
    }
}

class A {
    private void info(String name) {
        System.out.println(name);
    }
}
View Code

11 动态代理

技术分享
public class JDBCTest implements InvocationHandler{
    public static void main(String[] args) throws Exception {
        JDBCTest ih = new JDBCTest();
        Person p = (Person)Proxy.newProxyInstance(JDBCTest.class.getClassLoader(), Person.class, ih);
        p.walk();
        p.sayHello("dds");
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("   ---- " + method + "-----  ");
        if (args == null) {
            System.out.println("no args");
        } else {
            for (Object str : args) {
                System.out.println(str);
            }
        }
        return null;
    }
}

interface Person {
    void walk();
    void sayHello(String name);
}
View Code
技术分享
    public static <T> T newI(Class<T> c) {
        try {
            return c.newInstance();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
View Code

 




以上是关于类加载机制与反射的主要内容,如果未能解决你的问题,请参考以下文章

Java Review(三十九类加载机制与反射)

类加载机制与反射

Java注解与反射——获取反射对象 & 类加载机制

类加载机制与反射

Java反射与类加载过程会擦出什么样的火花

Java反射与类加载过程会擦出什么样的火花