JAVA反射(三)

一、使用反射时,setAccessible为true、false的性能差异

网上说直接new对象调用与采用反射调用,耗时差异大约30倍;setAccessible关闭与开启,耗时差异大约4倍。

可能是我测试机硬件配置足够的高的问题,setAccessible关闭与开启后,差异并不明显,大约有100ms的延迟。

测试结果:

普通方法调用,执行10亿次,耗时:697ms
反射动态调用,执行10亿次,耗时:1729ms
反射动态调用,跳过安全检查,执行10亿次,耗时:1664ms

测试源码:

package cn.foxsand.day03;

import cn.foxsand.day02.UserBean;

import java.lang.reflect.Method;

/**
 * 测试使用反射时,setAccessible为true、false的性能差异
 */
public class Demo01 {
    public static void test01(){
        UserBean u = new UserBean();
        long startTime = System.currentTimeMillis();

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

        long endTime = System.currentTimeMillis();

        System.out.println("普通方法调用,执行10亿次,耗时:" + (endTime - startTime) + "ms");
    }

    public static void test02(){
        String path = "cn.foxsand.day02.UserBean";
        try {
            UserBean u = new UserBean();
            Class clazz = u.getClass();
            Method m = clazz.getDeclaredMethod("getName" , null);
            long startTime = System.currentTimeMillis();

            for (int i = 0; i < 1000000000L; i++) {
                m.invoke(u , null);
            }
            long endTime = System.currentTimeMillis();

            System.out.println("反射动态调用,执行10亿次,耗时:" + (endTime - startTime) + "ms");
        }catch (Exception e1){
            e1.printStackTrace();
        }
    }

    public static void test03(){
        String path = "cn.foxsand.day02.UserBean";
        try {
            UserBean u = new UserBean();
            Class clazz = u.getClass();
            Method m = clazz.getDeclaredMethod("getName" , null);
            m.setAccessible(true);
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < 1000000000L; i++) {
                m.invoke(u , null);
            }
            long endTime = System.currentTimeMillis();

            System.out.println("反射动态调用,跳过安全检查,执行10亿次,耗时:" + (endTime - startTime) + "ms");
        }catch (Exception e1){
            e1.printStackTrace();
        }
    }

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

二、使用反射操作注解

2.1 测试相关类

package cn.foxsand.day01.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyTable01 {
    String value();
}
package cn.foxsand.day01.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyFileld {
    String columnName();
    String type();
    int     length();
}
package cn.foxsand.day01;

import cn.foxsand.day01.annotation.MyFileld;
import cn.foxsand.day01.annotation.MyTable01;

@MyTable01(value = "tb_student")
public class Student {
    @MyFileld(columnName = "id" , type = "int" , length = 10)
    private int id;
    @MyFileld(columnName = "studentName" , type = "varchar" , length = 10)
    private String studentName;
    @MyFileld(columnName = "age" , type = "int" , length = 10)
    private int age;

    public Student() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStudentName() {
        return studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

2.2 测试通过反射来操作注解信息

package cn.foxsand.day03;

import cn.foxsand.day01.Student;
import cn.foxsand.day01.annotation.MyFileld;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

/**
 * 使用反射读取注解
 */
public class Demo03 {
    public static void main(String[] args) {
        try {
            Class<Student> clazz = (Class<Student>) Class.forName("cn.foxsand.day01.Student");

            //获取类的所有有效注解
            Annotation[] annotations = clazz.getAnnotations();
            for (Annotation a1:annotations
                 ) {
                System.out.println(a1);
            }

            // 获取类中相应属性的有效注解
            Field f1 = clazz.getDeclaredField("studentName");
            MyFileld myFileld = f1.getAnnotation(MyFileld.class);
            System.out.println(myFileld);
        }catch (Exception e1){
            e1.printStackTrace();
        }
    }
}

测试结果:

@cn.foxsand.day01.annotation.MyTable01(value=tb_student)
@cn.foxsand.day01.annotation.MyFileld(columnName=studentName, type=varchar, length=10)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值