反射定义
所谓反射,可以理解为在运行时期获取对象类型信息的操作。
传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码。
严格地说,反射并非编程语言的特性,因为在任何一种语言都可以实现反射机制,但是如果编程语言本身支持反射,那么反射的实现就会方便很多。
Class类的使用
要弄懂反射,首先要了解Class类的使用
package com.saictest.demo.controller;
public class SystemUser {
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
@Test
public void testc() throws Exception {
SystemUser sysUser=new SystemUser();
Class<?> cls = Class.forName("com.saictest.demo.controller.SystemUser");
System.out.println(cls);
System.out.println(SystemUser.class);
System.out.println(sysUser.getClass());
System.out.println(SystemUser.class.getClass());
}
打印结果
class com.saictest.demo.controller.SystemUser
class com.saictest.demo.controller.SystemUser
class com.saictest.demo.controller.SystemUser
class java.lang.Class
-
一切皆对象,我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象,但是这些对象都不需要new出来,因为java.lang.Class类的构造方法是私有的
所以我们创建SystemUser 也是Class类的实例对象 -
获取Class对象(即 类类型 / 类型类)
获取有三种方式
- Class c1 = SystemUser.class
已知类名,直接通过类名.class获取该类的类型类- Class c1 = sysUser.getClass()
已知对象,通过sysUser.getClass()获取该类的类型类- Class c1 = Class.forName("com.saictest.demo.controller.SystemUser")
动态加载,通过Class.forName动态加载获取类型类
Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类。Object类中包含一个方法名叫getClass(),利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例,也就是我们常说的获取class对象。
从上面代码可以看出来sysUser是SystemUser的实例,所以我们可以通过sysUser.getClass()获取它的类型类。
-
引申
从上面代码里我们还看到一个奇怪的地方SystemUser.class.getClass(),为什么类型类还可以调用getClass方法呢,不是说只有实例对象才可以调用吗?这是因为SystemUser.class也是Class类的实例,所以可以调用getClass方法,调用结果返回类型类为class java.lang.Class。
System.out.println(c1==c2),返回结果为true
可以通过类的类类型创建该类的对象实例,即通过c1或c2创建SystemUser的实例。
SystemUserstu = (SystemUser)c1.newInstance();//前提是必须要有无参的构造方法,因为该语句会去调用其无参构造方法。该语句会抛出异常。