一. 基本概念
-
java文件编译后的class文件通过类加载器(classloader)加载到内存中以Class实例的形式存在。
-
通过下面的例子说明,通过不同的实例获取同一个类的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
-
运行程序时,Java虚拟机(JVM)首先检查所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。虚拟机只会产生一份字节码, 用这份字节码可以产生多个实例对象。
-
每个数组均属于一个 Class 类对象,所有具有相同元素类型和维数的数组共享一个Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。
-
通过以下方式,可获取到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对象的方式
- 使用实例 new Test().getClass();
- 由于对于同一类,只存在一个class文件,所以可以使用 Test.class
- 调用classloader中的loadClass方法(classloader中详细说明)
- 通过指定的路径调用 Class.forName("java.lang.Object");//获得Clss对象
二. class中常用的方法
-
getDeclaredField():获取该类声明的字段属性,一个类c,继承类b,实现接口a,b中存在属性P1,c中新增属性p2,将c向上转为a反射取field,只能取到p2
-
getSuperclass():获取父类的class
-
c.getDeclaredMethods():获取该类声明的方法,父类声明的,获取不到,父类抽象的方法,子类实现可以获取到,若为抽象类的class调用该方法,即使是抽象方法,也可获取到
-
c.getMethods():可以获取 到所有的方法,包括继承自父类的方法
-
getClassLoader():获取加载当前类的类加载器
-
newInstance():可以根据某个Class对象产生其对应类的实例。需要强调的是,它调用的是此类的无参默认构造方法。若不存在,会报错
-
isArray():判定此Class对象所对应的是否是一个数组对象
-
getInterfaces();//获取到该类的接口,若不存在,返回接口接应class数组为长度0