1 简介
Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象,这个Class对象是由JVM生成的,通过它能够获悉整个类的结构。要想使用反射,首先需要获得待操作的类所对应的Class对象。
Class类表示正在运行的Java应用程序中的类和对象,用来保存运行时类型标识(属于那个类)的类
java运行时系统一直对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息选准正确方法去执行,用来保存这些类型信息的类是Class类。Class类封装一个对象和接口运行时的状态,当装载类时,Class类型的对象自动创建。
- 不能显示声明一个Class对象,在加载类时虚拟机自动创建,通过调用类加载器的defineClass方法。
- jvm为每个类型都管理一个独一无二的Class对象。
- 没有公共构造函数
- 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。
每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。一般某个类的Class对象被载入内存,它就用来创建这个类的所有对象。
2 得到 Class对象的三种方法
调用Object类的getClass()方法
MyObject x;
Class c1 = x.getClass();使用Class类的中静态forName()方法获得与字符串对应的Class对象。例如:
Class.forName(“MyObject”)获取Class类型对象的第三个方法非常简单。如果T是一个Java类型,那么T.class就代表了匹配的类对象。例如
Class cl1 = Manager.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
注意:Class对象实际上描述的只是类型,而这类型未必是类或者接口。例如上面的int.class是一个Class类型的对象。由于历史原因,数组类型的getName方法会返回奇怪的名字。
3 总结
掌握常用的方法,
getClassLoader
,getName
,newInstance
,forName,getFileds,getDeclaredFields等
,掌握
Class.forName(className).getInstance()
与new class
的区别与实际中的应用。
- forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象。例如
Object obj = Class.forName(s).newInstance();- forName()就是装载类用的
- jvm在装载类时会执行类的静态代码段,静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了,而且以后不会再执行这段静态代码了。Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
- 使用 newInstance()方法就必须 保证 (1. 这个类已经加载, 2. 这个类已经连接, 这两个恰恰是
forName()
做的)- newInstance: 弱类型。低效率。只能调用无参构造。
- new: 强类型。相对高效。能调用任何public构造
- getFields()方法与getDeclaredFields()方法的区别(Class.getMethod()与getDeclaredMethod()等同理)
相同点 :getFields()方法和getDeclaredFields()方法都是获取类的属性;
不通点:getField()是获取的类的public声明的属性,包括集成而来的public修饰的属性;
getDeclaredFields()获取的是当前类声明的所有属性,包括private ,protect,public ,但是不包括集成自父类的属性