什么是反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。(百度百科)
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为“动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(了解一下)
JAVAclass对象生成:
比如,如今在Test包下有个User类。
1、User.class //返回值是Class<User>
2、new User().getClass() //返回值是Class<?>,若想得到User类型需要强制转换
3、Class.forName("test.User") //返回值是Class<?>,若想得到User类型需要强制转换 所以1是编译时加载,2,3是运行时加载
插曲:Class类介绍
Class是一个类,位于java.lang包下。
在Java中每个类都有一个相对应的Class类的对象,换句话说:Java程序在启动运行时 一个XXX.java类经过编译生成XXX.class文件后,就会在JVM虚拟机中产生一个XXX类对应的Class类的对象,用于表示这个XXX类的类型信息。
通过class对象获取类名,构造函数,属性,方法和一些其他方法:
一,获取类名:
System.out.println("获取全限定类名:\t" + userClass.getName());
System.out.println("获取类名:\t" + userClass.getSimpleName());
二,获取构造函数:
获取了构造函数,就可以去创建其对象了
User.class.getConstructors()://返回Constructor<?>对象,获取类中的公共构造方法
User.class.getConstructor(Class[] params): //若参数为User.Class返回Constructor<User>对象,获取类的特定公共构造方法,params参数指定构造方法的参数类型
User.class.getDeclaredConstructors()://返回Constructor<?>对象, 获取类中所有的构造方法(public、protected、default、private)
User.class.getDeclaredConstructor(Class[] params): //若参数为User.Class返回Constructor<User>对象,获取类的特定构造方法,params参数指定构造方法的参数类型
注:getConstructors()与getDeclaredConstructors()区别:
getConstructors()返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。
getDeclaredConstructors()这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。
三,实例化:
System.out.println("实例化:\t" + userClass.newInstance());
System.out.println("实例化:\t" +userClass.getConstructor(User.Class).newInstance());
四,获取属性:
User.class.getFields(): //获取类中public类型的属性,包括父类中的字段
User.class.getField(String name):// 获取类特定的方法,name参数指定了属性的名称
User.class.getDeclaredFields():// 获取类中所有的属性(public、protected、default、private),但不包括继承的属性。
User.class.getDeclaredField(String name): //获取类特定的方法,name参数指定了属性的名称
五,获取方法:
User.class.getMethods(): //获得类的public类型的方法
User.class.getMethod(String name, Class[] params): //获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型
User.class.getDeclaredMethods(): //获取类中所有的方法(public、protected、default、private)
User.class.getDeclaredMethod(String name, Class[] params): //获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型
注:在获取private属性和方法时:
// 取消安全性检查,设置后才可以获取或者修改private修饰的属性,也可以单独对某个属性进行设置
Field.setAccessible(fields, true);
// 取消安全性检查,设置后才可以调用private修饰的方法,也可以单独对某个方法进行设置
Method.setAccessible(methods, true);
六,其它重要方法:
forName(String className): //获取className参数指定的类的class对象
forName(String className,boolean initialize,ClassLoader): //使用指定的类加载器获取className参数指定的类的class对象
getClassLoader(): //获取类加载器
getPackage(): //获取类所在的包名
发现一:
if(new User().getClass()==User.class) { System.out.println("equal"); } else { System.out.println("unequal");
}
//结果输出equal,将其中一侧换成Class.forName("test.User")也时equal
证明三种获取class类对象方法获取的对象是同一个!
参考文献:https://www.cnblogs.com/xinhuaxuan/p/6019497.html