什么是 java 的反射机制呢?
在运行状 态中,对于任意一个类,都能够知道这个类的所有属性和方法, 对于任意一个对象,都能够调用他的任意一个方法和属性,种种动态的获取类的信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
Java 有 个 Object 类 ,是所有 java 类 的继承根源,其声明了多个可以在所有 java 类中被重写的方法,其中就 有 getClass()方法,该方法返回一个 Class 对象。
Class 类十分特殊。他和一般类一样继承与 Object , 他的实体用来表示 java 程序运行时的 classes 和 interface, 也用来表示 enum、array、int…。当一个 class 被加载,或当加载器的 defineClass()被 JVM 调用,JVM便自动产生一个 Class 对象。
反射机制的作用:
- 反编译:.class -> .java
- 通过反射机制访问 java 对象的属性、方法、构造方法等
反射机制获取类的Class对象有三种方法
- Class c1= Class.forName( “People”);
- java 中每个对象都有 class 属性。 Class c2 = Employee.class;
- java 中任何一个 java 对象都有 getClass() 方法。People p=new People(); Class c3 = p.getClass();
Class类常用方法
Class 类提供了大量的实例方法来获取该 Class 对象所对应的详细信息,Class 类大致包含如下方法:
获取公有的构造方法 : Constructor<T> getConstructor(Class<?>...Types)
包含的方法:Method getMethod(String name,Class<?>...Types)
包含的属性:Field getField(String name)
包含的注解:<A extends Annotation> A getAnnotation(Class<A>annotationClass)
内部类:Class<?> getDeclaredClasses()
外部类:Class<?> getDeclaringClasses()
所实现的接口:Class<?> [] getInterfaces()
修饰符: int getMoifiers()
所在包:Package getPackage()
类名:String getName()
简称: String getSimpleName()
getDeclaredConstructor(); //可以获取私有的构造方法(所有访问权限),私有属性和方法的获取类似
通过反射创建对象、获取类中的成员
获取类的Class对象以后我们可以通过Class对象来创建对象,利用 newInstance 方法
Class c = Class.forName(“People”)hg; //创建此 Class 对象所表示的类的一个新实例
Object o = c.newInstance(); //调用 People 的无参构造方法创建对象,相当于new了一个People对象
//反射出无参的构造方法并得到对象
String classname="org.example.hello.People";
Class class1 =Class. forName(classname);
Object object1=class1.newInstance();
System.out.println( object1.toString());
//反射出带参数的构造方法并得到对象
String classname2="org.example.hello.People";
Class class2 =Class. forName(classname2);
Constructor constructor1 = class2.getConstructor(String.calss,int.class); //int.class 表示是 int 类型,Integer.class 表示 java.lang.Integer 类型
System.out.println( object1.toString());
//获取方法
String classname3="org.example.hello.People";
Class class3 =Class. forName(classname3);
Method method=class3.getMethod("fun" , int.class);
method.invoke( object3,1); //invoke()方法用来执行获取到的方法。相当于“ .方法名”。
//获取属性
Object object=c.newInstance();
Field f=constructor.getDeclaredField("name"); //获取私有属性
f.setAccessible(true); //如果当前属性是私有,修改属性信息需要添加该代码,设访问权限
f.set(object, "zs"); //设置类中的私有属性信息
注:获取到类的私有成员,必须调用setAccessible(true);方法,才能使用