Java反射

什么是反射

简单来说:

反射是可以帮助程序员去获取类的详细信息的一种机制。

Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。

反射应用场景

  • 在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息
  • 比如:像 Spring/Spring Boot、MyBatis 等等框架中都大量使用了反射机制。

具体详细例子,JDK动态代理,利用反射获取方法的名字

public class DebugInvocationHandler implements InvocationHandler {
    /**
     * 代理类中的真实对象
     */
    private final Object target;

    public DebugInvocationHandler(Object target) {
        this.target = target;
    }


    public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
        System.out.println("before method " + method.getName());
        Object result = method.invoke(target, args);
        System.out.println("after method " + method.getName());
        return result;
    }
}

 优缺点

1、优点:

使代码更加灵活

2、缺点:

反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。

四种获取类信息的方式

public class TestClass2 {
    public static void main(String[] args) throws  Exception {
        //1.获取一个类的结构信息(类对象 Class对象)
        // 1.1Class.forName(类的完整路径字符串);
        Class clazz = Class.forName("java.lang.String");


        //1.2 类名.class
        Class clazz = String.class;


        //1.3 对象名.getClass()
        String str = "bjsxt";
        Class clazz = str.getClass();
        //Integer in = new Integer(20);


        //1.4 通过类加载器xxxClassLoader.loadClass()传入类路径获取:
        ClassLoader.getSystemClassLoader().loadClass("类的完整路径");


        //2.从类对象中获取类的各种结构信息
        System.out.println(clazz.getName());
        System.out.println(clazz.getSimpleName());
        System.out.println(clazz.getSuperclass());
        System.out.println(Arrays.toString(clazz.getInterfaces()));
    }
}

代码示例

public class TestField {
    public static void main(String[] args) throws Exception{
        //不使用反射操作属
//        Dog dog = new Dog();
//        dog.nickName = "旺财";
//        dog.age ="黑色";
//        System.out.println(dog.nickName);
//        System.out.println(dog.color);
        //使用反射操作属性  实际操作中使用反射直接操作属性也不多
        //1.获取类的完整路径字符串
        String className = "com.bjsxt.seq.Dog";
        //2.得到类对象
        Class clazz = Class.forName(className);
        //3.使用反射创建对象
        //Object dog = clazz.newInstance();
        Object dog = clazz.getConstructor().newInstance();
        //4.获取属性
        Field f1 =  clazz.getField("color");
       //Field f2 = clazz.getField("age");
        Field f2 = clazz.getDeclaredField("age");
        //5.给属性赋值
        f1.set(dog,"黑色1"); //  dog.color ="黑色";
        f2.setAccessible(true);//突破权限的控制
        f2.set(dog,10);
        //6.输出给属性
        System.out.println(f1.get(dog)); //dog.color
        System.out.println(f2.get(dog)); //dog.age
        System.out.println(dog);
    }
}
使

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值