反射的作用、反射方法调用与普通方法性能测试

反射

通过反射可以做的事:

  • 获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等
public class 1213lianxi {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class class1 = Class.forName("com.kuang.reflection.User");      System.out.println("===========================================");

        System.out.println(class1.getName()); // 包名 + 类名
        System.out.println(class1.getSimpleName()); //类名

        System.out.println("===========================================");
        //获得字段 :
        Field[] fields = class1.getFields(); //只能获得public的属性
        System.out.println(fields.length);

        Field[] fields2 = class1.getDeclaredFields(); //返回全部的属性,可以获得私有的
        System.out.println(fields2.length);

        for (Field field : fields2) {
            System.out.println("field=>\t"+field);
        }

        Field name = class1.getDeclaredField("name"); //获取指定的字段!
        System.out.println(name);

        //获得方法 
        System.out.println("===========================================");

        Method[] methods = class1.getMethods(); //返回当前类和被继承的类的public方法
        System.out.println(methods.length);

        for (Method method : methods) {
            System.out.println("methods: "+method);
        }

        Method[] declaredMethods = class1.getDeclaredMethods(); //获得当前类的所有方法
        System.out.println(declaredMethods.length);

        for (Method method : declaredMethods) {
            System.out.println("declaredMethods: "+method);
        }

        System.out.println("=====");
     
  • 获取任意对象的属性,并且能改变对象的属性
public class 1213lianxi {
//创建对象,new  无参,有参!
//通过指定构造器创建对象! new User(1, 3, "lianxi");



    public static void main(String[] args) throws Exception {

        Class c1 = Class.forName("org.westos.191213demo");
        
        System.out.println("==========================================");
        User user1 = (User) c1.newInstance(); 
        System.out.println(user1); 

        System.out.println("==========================================");
       Constructor declaredConstructor = c1.getDeclaredConstructor(int.class, int.class, String.class);
        User user2 = (User) declaredConstructor.newInstance(1, 3, "lianxi");
        System.out.println(user2);

        System.out.println("==========================================");
        User user3 = (User) c1.newInstance();
       //1. 获得你要操作的方法
        Method setName =c1.getDeclaredMethod("setName",String.class);
        //2. 通过invoke方法执行方法  
        setName.invoke(user3,"lhy3");
        System.out.println(user3.getName());
        System.out.println("==========================================");
        User user4  = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //显示调用setAccessible为true,则可以访问private方法!
        name.setAccessible(true);
        name.set(user4,"lhy4");
        System.out.println(user4.getName());

    }

}
  • 调用任意对象的方法

  • 判断任意一个对象所属的类

  • 实例化任意一个类的对象

import java.lang.annotation.ElementType;

public class Test4 {
    public static void main(String[] args) {

        Class c1 = Object.class; //class
        Class c2 = Comparable.class; //接口
        Class c3 = String[].class; // 数组
        Class c4 = String[][].class; // 二维数组
        Class c5 = ElementType.class; //枚举类型
        Class c6 = Override.class; // 注解
        Class c7 = Integer.class; //基本数据类型
        Class c8 = void.class; //void
        Class c9 = Class.class; //反射对象本身

  
        int[] a = new int[10];
        String[] b = new String[100];

        Class c10 = a.getClass();
        Class c11 = b.getClass();

        System.out.println(c10);
        System.out.println(c11);

        System.out.println(c10==c11);


        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);

    }
}

分析性能问题

public class 1214lianxi {

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test3();
    }

    public static void test1(){
        User user = new User();
        long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000000L ; i++) {
            user.getName();
        }

        long end = System.currentTimeMillis();
        System.out.println("普通方法调用执行10亿次:"+(end-start)+"ms"); //558ms
    }

    public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class class1 = user.getClass();
        Method getName = class1.getDeclaredMethod("getName", null);
        long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000000L ; i++) {
            getName.invoke(user,null);
        }

        long end = System.currentTimeMillis();
        System.out.println("反射方法调用执行10亿次:"+(end-start)+"ms"); //3883ms
    }

    public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class class1 = user.getClass();
        Method getName = class1.getDeclaredMethod("getName", null);

        getName.setAccessible(true); 

        long start = System.currentTimeMillis();

        for (int i = 0; i < 1000000000L ; i++) {
            getName.invoke(user,null);
        }

        long end = System.currentTimeMillis();
        System.out.println("反射方法调用执行10亿次:"+(end-start)+"ms"); //2400ms
    }
}

通过代码可以得知,反射的性能消耗很大!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值