运用反射动态创建对象以及调用属性的三种方法的性能对比

关于反射的一些方法和技巧琢磨半天害怕自己忘了,于是乎写到博客里给我以后看看,源码如下:

package cn.sjy;

import java.util.Arrays;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2020/11/1 19:33
 * 通过反射如何获取方法,构造器,属性等
 */
public class Test5 {
    
    
    public static void main(String[] args ) throws Exception{
    
    
        Class c1 = Class.forName("cn.sjy.Person");

        //获取类的名字
        System.out.println(c1.getName());
        //获取类的简化的名字
        System.out.println(c1.getSimpleName());

        //获取类的属性
        System.out.println("===================");
        //只能找到public修饰的属性
        System.out.println(Arrays.toString(c1.getFields()));
        //可以找到private修饰的属性
        System.out.println(Arrays.toString(c1.getDeclaredFields()));
        //获取指定的属性
        System.out.println(c1.getDeclaredField("name"));

        //获取类的方法
        System.out.println("===================");
        //获取所有的public修饰的方法,并且可以把继承的方法也打印出来
        System.out.println(Arrays.toString(c1.getMethods()));
        //获取所有的方法,仅仅是本类
        System.out.println(Arrays.toString(c1.getDeclaredMethods()));
        //获取指定的方法
        System.out.println(c1.getMethod("getId"));

        System.out.println("=======================");
        //获得指定的构造器
        System.out.println(Arrays.toString(c1.getConstructors()));
        System.out.println(c1.getConstructor(int.class,String.class));
    }
}

package cn.sjy;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2020/11/1 19:34
 * 动态创建对象,通过反射
 */
public class Test4 {
    
    
    public static void main(String[] args ) throws Exception{
    
    
        //获取Class对象
        Class c1 = Class.forName("cn.sjy.Person");
        //实例化该对象,创建由此类对象表示的新的对象
        Person person = (Person) c1.newInstance();
        //newInstance()方法规定调用无参的构造函数
        System.out.println(person);

        //获得一个类的构造器
        Person person2 = (Person)c1.getConstructor(int.class, String.class).newInstance(2017021, "虎哥");
        //将这个类的构造器进行实例化
        System.out.println(person2);

        //调用一个普通方法
        Method fan = c1.getDeclaredMethod("fan");
        //需要忽略访问权限修饰符的安全检查--》暴力反射
        fan.setAccessible(true);
        fan.invoke(person);

        //操作属性
        Field id = c1.getDeclaredField("id");
        id.setAccessible(true);
        id.set(person,123);
        System.out.println(id.get(person));
    }
}

Person类

package cn.sjy;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    
    
    private int id;
    private String name;

    /**普通方法*/
    private void fan(){
    
    
        System.out.println("通过反射来调用普通方法!");
    }
}

普通方法,反射(打开检测),反射(关闭检测)三种性能对比分析:

package cn.sjy;

import java.lang.reflect.Field;

/**
 * @author Shi Jun Yi
 * @version 1.0
 * @date 2020/11/1 21:03
 */
public class Test6 {
    
    
    /**
     * 普通方法调用
     */
    public static void test01() throws Exception{
    
    
        Person person = new Person();
        //获取系统当前时间
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
    
    
            person.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方法执行10亿次:"+(endTime-startTime)+"ms");
    }

    /**
     * 反射调用 打开检测
     */
    public static void test02() throws Exception{
    
    
        Class<Person> c = Person.class;
        Field id = c.getDeclaredField("id");
        //获取系统当前时间
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
    
    
            id.get(c.newInstance());
        }
        long endTime = System.currentTimeMillis();
        System.out.println("运用反射打开检测执行10亿次:"+(endTime-startTime)+"ms");
    }

    /**
     * 反射调用 关闭检测
     */
    public static void test03() throws Exception{
    
    
        Class<Person> c = Person.class;
        Field id = c.getDeclaredField("id");
        id.setAccessible(true);
        //获取系统当前时间
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 1000000000; i++) {
    
    
            id.get(c.newInstance());
        }
        long endTime = System.currentTimeMillis();
        System.out.println("运用反射关闭检测执行10亿次:"+(endTime-startTime)+"ms");
    }

    public static void main(String[] args ) throws Exception{
    
    
        test01();;
        test02();;
        test03();;
    }
}

结果如下
在这里插入图片描述
由此可得出结论,普通方法的执行效率很高,反射的执行效率较低,当调用反射比较多的时候可以关闭检测以提高效率。
未完,待续~~

猜你喜欢

转载自blog.csdn.net/weixin_44475741/article/details/109437065