Java 反射“简单易懂版“ —— 基础使用(一)

反射的功能虽然不常用,但是也会出现 “书到用时方恨少” 的情况,索性今天来将他搞扎实些,同时希望能帮助到有同样需求的同学~

反射的两个重要作用

  • 反编译:.class -> .java
  • 通过反射访问 Java 对象的 属性方法构造方法等 (最常用的)
反射机制需要使用的类
  • java.lang.Class

第一步 拿到Class 对象(起源)

水是有源的,树是有根的,使用反射就要先拿到 ‘根’ —— > Class 对象

献上zhang san
public class ZhangSan {

   private String name;
   private int age;

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

    private String quickRun(String cause){
        System.out.println(cause);
        return cause;
    }

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


public class Person {
    public String type = "人类";
}
举例 获取 ZhangSan 的 Class 对象

方式 1: 会让ClassLoader 装载类,并‘进行初始化

   		Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan"); //传入包名+类名路径
        	System.out.println(zhang3Class); //打印:class reflectTest.ZhangSan

方式 2: ClassLoader 装在入内存,但‘不对类进行初始化

        Class c2 = ZhangSan.class;
        System.out.println(c2); //打印:class reflectTest.ZhangSan

方式 3: 返回类对象运行时真正的所指对象 的Class对象 (对于反射而言没什么用)

        Class c3 = new ZhangSan("Zhang3", 18).getClass();
        System.out.println(c3); //打印:class reflectTest.ZhangSan
重点是记住前两中方式的区别就好了(是/否 对类进行初始化)
获取 Object

方式 1: 获取无参构造对象

        // 获取无参构造对象
        Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan");
        Object z3Obj =zhang3Class.getDeclaredConstructor().newInstance();//Java 9 开始使用
        //Object z3Obj = zhang3Class.newInstance(); //Java 8 使用

方式 2: 获取有参构造对象

        Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan");
        Object z3Obj = zhang3Class.getDeclaredConstructor(String.class,int.class).newInstance("zhang33", 19); //Java 9 开始使用
//        Object z3Obj = zhang3Class.getConstructor(String.class,int.class); //Java 8 使用
//        Object z3Obj = zhang3Class.newInstance("zhang33", 19); //Java 8 使用
反射类中的属性

反射私有的 ‘name’ 属性
打印 ZhangSan{name=‘li si’, age=19} 修改私有属性成功!

        Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan");
        Object z3Obj = zhang3Class.getDeclaredConstructor(String.class,int.class).newInstance("zhang33", 19); //Java 9 开始使用
		System.out.println(z3Obj); // ZhangSan{name='zhang33', age=19}
		
        Field nameField = zhang3Class.getDeclaredField("name");
        nameField.setAccessible(true); //改变属性访问限制 (可以访问私有属性了)
        nameField.set(z3Obj,"li si");
        System.out.println(z3Obj); // ZhangSan{name='li si', age=19}

Field 描述的是属性对象,其中包含很多信息 比如:属性名字 属性类型 属性注解(使用这些可以做很多事情~ ~ 后面会说)

反射类中的方法
        Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan");
        Object z3Obj = zhang3Class.getDeclaredConstructor(String.class,int.class).newInstance("zhang33", 19); //Java 9 开始使用
        Method quickRun = zhang3Class.getDeclaredMethod("quickRun",String.class); //方法名称 + 方法入参的类型 有几个入参填几个
        quickRun.setAccessible(true); //改变属性访问限制 (可以访问私有方法了)
        quickRun.invoke(z3Obj, "Lun Xiang 来了!!");
获取父类Class

getSuperclass

        Class<?> zhang3Class = Class.forName("reflectTest.ZhangSan");
        Class<?> superclass = zhang3Class.getSuperclass();

反射进阶

进阶(1) Api 作用域

上面叙述了,获取 属性方法 的Api ,但是在有些场景会拿不到对应的对象,实际上是每个Api 的作用域不同导致的。

获取属性作用域

方法本ClassSuperClass
getFieldpublicpublic
getDeclareFieldpublic 、procted 、privateno
getFieldspublicpublic
getDeclareFieldspublic 、procted 、privateno

获取方法作用域

方法本ClassSuperClass
getMethodpublicpublic
getDeclareMethodpublic 、procted 、privateno
getMethodspublicpublic
getDeclareMethodspublic 、procted 、privateno

获取构造作用域

方法本ClassSuperClass
getConstructorpublicno
getDeclareConstructorpublic 、procted 、privateno
getConstructorpublicno
getDeclareConstructorpublic 、procted 、privateno

反射创建一个对象, java 9 已经废弃了 class.newInstance();
所以直接用 class.getConstructor().newInstance() 吧;

小结:这一节介绍了反射当中常用的基础知识,
1、 获取 Class Object ;
2、 获取 属性 方法 ;
3、 Api 的作用域

如果想了解 反射实现动态代理 的同学,请看 下一节 Java 反射 “实现动态代理” —— 进阶使用(二))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值