能够分析类能力的程序称为反射。反射机制的功能极其强大,反射机制可以用来:
- 在运行时分析类的能力
- 在运行时查看对象,例如,编写一个toString方法供所有类使用
- 实现通用的数组操作代码
- 利用Method对象
1.Class类
在程序运行期间,Java运行时系统始终为所有的对象维护一个被称为运行时的类型标识。保存这些运行时信息的类被称作Class类。Object类中的getClass()方法将返回一个Class类型的实例。
一个Class对象将表示一个特定的类运行时的各种信息。最常用的Class方法是getName(),这个方法返回类的名字。
Employee e = new Employee("YinHang");
System.out.println(e.getClass().getName() + " " + e.getName());
//输出 Employee YinHang
还可以调用静态方法forName获得类名对应的Class对象。
String className = "java.util.Random";
Class cl = Class.forName(className);
除此之外,如果T是任意的Java类型(或void关键字),T.class将代表匹配的Class类对象。
Class cl1 = Random.class;
Class cl2 = int.class;
Class cl3 = Double[].class;
一个Class对象实际上表示的是一个类型,而这个类型未必一定是一种类。例如:int不是类,但int.class是一个Class类型的对象。Class类实际上是一个泛型类。例如:Employee.class的类型是Class<Employee>。
虚拟机为每个类型管理一个Class对象。因此可以利用"=="运算符实现两个Class类对象比较的操作。(属于同一个类型)
if(e.getClass() == Employee.class)
还有一个很有用的方法newInstance(),可以用来动态地创建一个类的实例。例如,
e.getClass().newInstance();
Class.forName("java.util.Random").newInstance();
Empolyee.class.newInstance();
但以上Class.newInstance()方法只能调用无参数的构造器,如果要调用有参数的构造器,需要使用Constructor类中的newInstance(Object...args)方法。其中Obejct...args参数代表构造器所需要的各种参数。
e.getClass().getDeclaredConstructor().newInstance(Obejct...args);
总结:
- Class对象表示某一类型运行时的各种信息。
- 获得Class对象的三种方法:
- object.getClass()
- Class.forName()
- T.class
- 两个Class对象比较使用"=="运算符即可
- 动态地创建一个类的实例,使用Constructor类中的newInstance(Object...args)方法。
2.类的加载
Java类的加载:编译器将.java文件编译成.class文件加载到JVM中,在内存中生成Java.lang.class对象。
之所以要加载类是因为JVM并不是在项目运行时就把所有的类文件加载到JVM,而是当类需要的的时候,才去加载。
Class.forName()、new关键字、ClassLoader.loadClass区别
- Class.forName()除了将类的.class文件加载到JVM中之外,还会对类进行解释,执行类中的static块。
- ClassLoader只干一件事情,就是将.class文件加载到JVM中,不会执行static中的内容。
- new关键字与Class.forName.newInstance()的区别在于,new关键字可以调用带参数的构造器,而后者不能。
网友评论