动态创建对象执行方法
创建类的对象,调用Class对象的NewInstance()方法
- 类必须有一个无参数的构造器
- 类的构造器的访问权限需要足够
调用指定的方法
通过反射,调用类中的方法,通过Method类完成。
- 通过Class类的getMethod(String name,Class…parameterTypes)方法取得一个Method对象,并设置此方法操作时所需要的参数类型。
- 之后使用Object invoke(Object obj,Object[] args)进行调用,并向方法中传递要设置的obj对象的参数信息
Object invoke (Object obj, Object…args)
- Object 对应原方法的返回值,若原方法无返回值,此时返回 null
- 若原方法若为静态方法,此时形参Object obj可为null
- 若原方法形参列表为空,则Object[ ] args为null
- 若原方法为 private,则需要在调用此invoke()方法之前,显式调用方法对象的setAccessible(true) 方法,可访问private的方法
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
//动态创建对象,通过反射
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得Class对象
Class c1 = Class.forName("Reflection.User");
//构造一个对象
// User user = (User)c1.newInstance(); //本质是调用了类的无参构造器
// System.out.println(user);
//通过构造器创建对象
Constructor con = c1.getDeclaredConstructor( int.class,String.class, int.class);
User user11 = (User) con.newInstance(001, "XXX", 18);
System.out.println(user11);
//通过反射调用普通方法
User u = (User)c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke :激活的意思
//(对象,"方法值")
setName.invoke(u,"XXXXX");
System.out.println(u.getName());
//通过反射操作属性
System.out.println("------------------------------");
User u21=(User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序权限的安全检测
name.setAccessible(true);
name.set(u21,"AAAAA");
System.out.println(u21.getName());
}
}
setAccessible
- Method 和 Field Constructor 对象都有SetAccessible()方法
- setAccessible作用时启动和禁用访问安全检查的开关
- 参数值为ture则指示反射的对象在使用时应该取消Java语言访问检查
- 提高反射的效率。如果代码中必须用反射,而该句代码需要频繁的被调用,那么请设置为True
- 使得原本无法访问的私有成员也可以访问
- 参数值为False则指示反射对象应该实施Java语言访问检查
案例 普通方法 反射方式 和 反射方式 关闭检测比较速度
package Reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test09 {
//普通方法
public static void test1(){
User u=new User();
long startTime=System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
u.getName();
}
long entTime=System.currentTimeMillis();
System.out.println("时间为:"+(entTime-startTime)+"ms");
}
//反射方式调用
public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User u=new User();
Class c1 = u.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime=System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(u,null);
}
long entTime=System.currentTimeMillis();
System.out.println("时间为:"+(entTime-startTime)+"ms");
}
//反射方式调用 关闭检测
public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User u=new User();
Class c1 = u.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime=System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(u,null);
}
long entTime=System.currentTimeMillis();
System.out.println("时间为:"+(entTime-startTime)+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test1(); //10ms
test2(); //4083ms
test3(); //1649ms
}
}