动态创建对象执行方法

动态创建对象执行方法

创建类的对象,调用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
    }

}

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值