反射学习记录

1、什么是反射

能够分析类能力的程序称为反射

2、获取类对应的Class类三种方法

每一个类对应的只有一个Class类,当然注解、接口、数组、数据类型都有对应的Class类,那怎么获取对应的Class类

这个要用到的Userclass User {
    private String name;
    private int age;
    private String passworld;
    public String address;

    public User() {
    }

    public User(String name, int age, String passworld) {
        this.name = name;
        this.age = age;
        this.passworld = passworld;
    }

    private User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

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

    public String getPassworld() {
        return passworld;
    }

    public void setPassworld(String passworld) {
        this.passworld = passworld;
    }

    private void test(){
        System.out.println("this is a test!");
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", passworld='" + passworld + '\'' +
                '}';
    }
}
		//1、通过调用Class类中的静态方法forName
        Class c1 = Class.forName("reflective.User");
        //2、通过对象后加.class
        Class c2 = User.class;
        //3、通过实例对象的getClass方法,该方法继承自Object类
        User user = new User();
        Class c3 = user.getClass();

因为每个类对应的生成的只有一个Class类,所以上面的c1、c2、c3都是相等的

3、通过反射创建实例

		//通过Class对象创建对应的实例
        User u1 = (User)c1.newInstance();
        System.out.println(u1.toString());
        //通过Class对象的构造器创建对应的实例(推荐)
        User u2 = (User)c1.getConstructor().newInstance();
        System.out.println(u2.toString());

这个步骤中的c1为第二步中c1

4、通过反射获取类的结构

反射可以获取类的属性、方法、构造器
代码如下:

//通过Class返回对应类的属性
//Field[] fields = c1.getFields(); //返回公有域属性(包括继承的)
Field[] fields = c1.getDeclaredFields(); //返回所有域属性(包括继承的)
for (Field field : fields) {
       System.out.println(field);
}
        System.out.println("------------------");
//Method[] methods = c1.getMethods(); //返回所有公有域方法(包括继承的)
 Method[] methods = c1.getDeclaredMethods(); //返回所有域方法(包括继承的)
        for(Method method : methods) {
            System.out.println(method);
        }
        System.out.println("---------------");
//Constructor[] constructors = c1.getConstructors();//返回所有公有域构造器
   Constructor[] constructors = c1.getDeclaredConstructors();//返回所有构造器
        for(Constructor constructor : constructors) {
            System.out.println(constructor);
        }

5、通过反射获取具体的值

一般来说被private修饰的属性,方法、构造器都不能被直接访问,但是反射可以,setAccessible方法默认值是false,是用来安全检测,当该方法参数设置为true,就可以访问

		
		User user2 = new User("小明", 11, "123456");
        Class c4 = user2.getClass();
        Field f = c4.getDeclaredField("name");
        f.setAccessible(true);
        System.out.println(f.get(user2));
        //反射不仅可以访问到值,还可以设置值
        f.set(user2,"小红");
        System.out.println(f.get(user2));

        Method m = c4.getDeclaredMethod("test");
        m.setAccessible(true);
        //这是通过反射调用方法
        m.invoke(user2);
        System.out.println(m);

6、反射耗性能

package com.wgr.reflective;

import java.lang.reflect.Method;

/**
 * @author weiguorong
 * @date 2021/8/13 0:04
 */
public class Test {

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        System.out.println(test.test01());
        System.out.println(test.test02());
        System.out.println(test.test03());
    }

    //普通调用
    public long test01() {
        User user = new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

    //反射调用
    public long test02() throws Exception {
        User user = new User();
        Class c1 = user.getClass();
        Method method = c1.getMethod("getName");
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 100000000; i++) {
            method.invoke(user, null);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

    //取消安全检测的反射调用
    public long test03() throws Exception {
        User user1 = new User();
        Class c1 = user1.getClass();
        Method method = c1.getMethod("getName");
        long startTime = System.currentTimeMillis();
        method.setAccessible(true);
        for (int i = 0; i < 100000000; i++) {
            method.invoke(user1, null);
        }
        long endTime = System.currentTimeMillis();
        return endTime - startTime;
    }

}
class User {
    String name;

    public User() {
    }

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

结果
63
18075
828
所以反射是三个中最耗性能的

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值