1. jvm之class

一. 基本概念

  1. java文件编译后的class文件通过类加载器(classloader)加载到内存中以Class实例的形式存在。

  2. 通过下面的例子说明,通过不同的实例获取同一个类的class实例,结果相同,说明.class类加载到内存中只会存在一份

Test t1 = new Test();
Test t2 = new Test();
Class c1 = t1.getClass();
Class c2 = t2.getClass();
Class c3 = Class.forName("com.Test");
System.out.print( c1 == c2);//true
System.out.print( c1 == c3);//true
  1. 运行程序时,Java虚拟机(JVM)首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。

  2. 每个数组均属于一个 Class 类对象,所有具有相同元素类型和维数的数组共享一个Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。

  3. 通过以下方式,可获取到Integer的基本数据对像,传入的是Integer.class;通过
    getType(Integer.class).getClass().getClassLoader()可获取到int的class对象及classloader

public static Object getType(Class c) throws Exception {
    Field f = c.getDeclaredField("TYPE");
    Object obj = f.get(c);
    return obj;
}

二. 获取class对象的方式

  1. 使用实例 new Test().getClass();
  2. 由于对于同一类,只存在一个class文件,所以可以使用 Test.class
  3. 调用classloader中的loadClass方法(classloader中详细说明)
  4. 通过指定的路径调用 Class.forName("java.lang.Object");//获得Clss对象

二. class中常用的方法

  1. getDeclaredField():获取该类声明的字段属性,一个类c,继承类b,实现接口a,b中存在属性P1,c中新增属性p2,将c向上转为a反射取field,只能取到p2

  2. getSuperclass():获取父类的class

  3. c.getDeclaredMethods():获取该类声明的方法,父类声明的,获取不到,父类抽象的方法,子类实现可以获取到,若为抽象类的class调用该方法,即使是抽象方法,也可获取到

  4. c.getMethods():可以获取 到所有的方法,包括继承自父类的方法

  5. getClassLoader():获取加载当前类的类加载器

  6. newInstance():可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的无参默认构造方法。若不存在,会报错

  7. isArray():判定此Class对象所对应的是否是一个数组对象

  8. getInterfaces();//获取到该类的接口,若不存在,返回接口接应class数组为长度0