首先想要远程执行某一个类的某一个方法,或在程序执行中动态执行某一个类的某一个方法就要用到反射。
JAVA反射机制是在运行状态中,对于任意一个类 (class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个属性和方法;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
一、如何得到反射类:(以Person类为栗子,文末贴出)
1. Object类中的getClass()方法的。想要用这种方式,必须要明确具体的类,并创建对象。特点:麻烦
Person p=new Person();
Class clazz= p.getClass();
2. 任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。相对简单,但是还是要明确用到类中的静态成员。特点:扩展性不强
Class clazz2=Person.class;
3. 一个类只可能是Class类的一个实例对象,
只要通过给定的类的字符串名称就可以获取该类,用Class类中的
forName
方法完成。
这种方式只要有具体名称即可。
特点:
方便,扩展性强
Class clazz4=Class.forName("reflect.Person");
对构造函数的操作,在反射机制中有两种方法
1、针对无变量的构造方法,直接调用Class类中的newInstance()
Object obj=clazz.newInstance();//此时调用的是无参数构造函数
显示结果为:
无参构造函数...
2、针对带参数的构造方法,需要先调用该Class对象的getConstructor()方法获得一个专属的Constructor的对象,再调用Constructor类中newInstance()方法。
Constructor<?> constructor=clazz.getConstructor(String.class,int.class);//获取到了指定的构造函数对象
Object obj1=constructor.newInstance("章北海",18);//通过该构造器对象的newInstance方法进行对象的初始化
显示结果为:
有参构造函数...章北海18
在这里需要说明的是只有两个类拥有newInstance()方法,分别是Class类和Constructor类。
Class类的newInstance()方法是不带参数的,而Constructor类的newInstance()方法是带参数的需要提供必要的参数。
三、对属性的操作
在java.lang.reflect.Field中,Field类封装了关于成员变量的操作。以下为部分方法
---getField() 得到指定名称的属性 (强调公有属性,包含继承下来的)
---getFields() 得到所有属性(强调公有属性,包含继承下来的)
---getDeclaredField()得到指定名称的属性 (所有属性,强调的本类中属性)
---getDeclaredFields()得到所有属性 (所有属性,强调的本类中属性)
----get(Object obj) 返回指定对象上此 Field 表示的字段的值。
----getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java 语言修饰符。
----getName() 返回此 Field 对象表示的字段的名称。
----getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
----set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
----setAccessible(true);设置安全检查,如果设为true,表示可以进行修改字段值
Field field=clazz1.getField("name");//getField()只能获取公有的,运行会出错
Field field=clazz1.getDeclaredField("age");//getDeclaredField()只获取本类,但包含私有
//对私有字段的访问取消权限检查。暴力访问
field.setAccessible(true);
Object obj=clazz1.newInstance();
field.set(obj, 22);
Object o=field.get(obj);
System.out.println(o);
显示结果为:
private int reflect.Person.age
无参构造函数...
22
四、对方法的操作
-----getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法
-----getMethods() 返回一个包含某些 Method 对象的数组
---- getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象本类中所有的方法
-----getDeclaredMethods() 返回一个包含所有DeclaredMethod对象的数组
Method[] method1=clazz2.getMethods();
for(Method method:method1){
System.out.println(method+"...getMethods()");
}
Method[] method2=clazz2.getDeclaredMethods();
for(Method method:method2){
System.out.println(method+"...getDeclaredMethods()");
}
Method method=clazz2.getMethod("publicMethod", String.class,int.class);
Object obj=clazz2.newInstance();
method.invoke(obj, "云天明",8);
显示结果为:
public void reflect.Person.publicMethod(java.lang.String,int)...getMethods()
public void reflect.Person.show()...getMethods()
public static void reflect.Person.staticMethod()...getMethods()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException...getMethods()
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException...getMethods()
public final void java.lang.Object.wait() throws java.lang.InterruptedException...getMethods()
public boolean java.lang.Object.equals(java.lang.Object)...getMethods()
public java.lang.String java.lang.Object.toString()...getMethods()
public native int java.lang.Object.hashCode()...getMethods()
public final native java.lang.Class java.lang.Object.getClass()...getMethods()
public final native void java.lang.Object.notify()...getMethods()
public final native void java.lang.Object.notifyAll()...getMethods()
public void reflect.Person.publicMethod(java.lang.String,int)...getDeclaredMethods()
public void reflect.Person.show()...getDeclaredMethods()
private void reflect.Person.privateMethod()...getDeclaredMethods()
public static void reflect.Person.staticMethod()...getDeclaredMethods()
无参构造函数...
公有的有参数成员方法...云天明:8
Person类:
package reflect;
public class Person {
private String name;
private int age;
public Person(){
System.out.println("无参构造函数...");
}
public Person(String name,int age){
this.name=name;
this.age=age;
System.out.println("有参构造函数..."+name+age);
}
public void show(){
System.out.println("公有的无参数成员方法..."+name+age);
}
private void privateMethod(){
System.out.println("私有的无参数成员方法...");
}
public void publicMethod(String name,int age){
System.out.println("公有的有参数成员方法..."+name+":"+age);
}
public static void staticMethod(){
System.out.println("静态的无参数成员方法...");
}
}