反射机制

Class类:

所有类的对象实际上都是class类的一个实例。Java.lang.Class

当一个类被加载以后,JVM会生成可执行的代码和数据

还会在堆内存中创建一个对应的该类的class对象

这个class类对象中包含该类的整个结构信息

同一个类只能被java虚拟机加载一次,在堆内存中是唯一存在的

 

类的使用

1.Class.forName()最常用

反射的基本原理:

Class类实际上是java反射的源头

反射机制,java动态获取指定的类以及动态调用类中的内容

在程序运行过程中,通过已知的对象信息来找到所属类,并将该类加载到内存中,通过反射

来新建对象

 

反射应用场景:

如果编码时,不知道类的具体信息,就可以通过已知对象来获取对象所在的类的信息

 

保留无参的构造方法

 

 

 

类。Class

对象。Getclass

 

取得类的全名称

取得类属性的信息field类

取得public类型的全部信息,返回一个对象数组

可以获得私有属性:

获得指定属性:

 

获取类的方法信息:Method类

 

取得类的构造器信息Constructor类

取得public类型

取得所有类型的构造器信息

 

获得某一个构造器:

 

获取继承的父类信息:

取得所实现的全部接口信息:

 

利用无参构造器创建对象

Newinstance方法:

 

利用有参的构造器创建一个对象:

 

利用反射API,调用普通方法

 

 

利用反射API,操作属性:

 

实操:

本示例使用Java反射机制分别设置当前类的private、public属性以及其父类的private属性来说明如何通过Java反射机制设置属性值。(注:设置继承的父类属性时,无法通过当前类的Class对象直接获取其属性字段,须通过其父类Class对象得到Field对象操作)
首先,建立父类User

  

 public class User {
        private String name;
        private int age;
     
        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;
        }
    }

建立子类Student继承User

  

 public class Student extends User {
        //学号
        private String stuNo;
        //专业
        public String major;
     
        public String getStuNo() {
            return stuNo;
        }
     
        public void setStuNo(String stuNo) {
            this.stuNo = stuNo;
        }
     
        public String getMajor() {
            return major;
        }
     
        public void setMajor(String major) {
            this.major = major;
        }
    }

新建测试类

   

public class Test {
        public static void main(String[] args) throws Exception {
            Object stu = new Student();
            Class clazz = stu.getClass();
            System.out.println("-------设置当前类stuNo(private)属性---------------");
            System.out.println("Before stuNo:"+((Student)stu).getStuNo());
            Field stuNo = clazz.getDeclaredField("stuNo");//通过反射获取stuNo字段
            stuNo.setAccessible(true);//private属性必须设置
            stuNo.set(stu,"13201233");
            System.out.println("After stuNo:"+((Student)stu).getStuNo());
            
            System.out.println("-------设置当前类major(public)属性---------------");
            System.out.println("Before major:"+((Student)stu).getMajor());
            Field major = clazz.getDeclaredField("major");//通过反射获取stuNo字段
            major.set(stu,"软件工程");
            System.out.println("After major:"+((Student)stu).getMajor());
     
            System.out.println("-------设置继承的父类name属性------------");
            System.out.println("Before name:"+((Student)stu).getName());
            Field name = clazz.getSuperclass().getDeclaredField("name");//通过反射获取父类name字段
            name.setAccessible(true);//private属性必须设置
            name.set(stu,"Edward");
            System.out.println("After name:"+((Student)stu).getName());
        }
    }

运行结果:

    -------设置当前类stuNo(private)属性---------------
    Before stuNo:null
    After stuNo:13201233
    -------设置当前类major(public)属性---------------
    Before major:null
    After major:软件工程
    -------设置继承的父类name属性------------
    Before name:null
    After name:Edward

注意:设置private属性值时,必须设置setAccessible(true),否则会抛出如下异常:

    Exception in thread "main" java.lang.IllegalAccessException: Class cn.ll.test.Test can not access a member of class cn.ll.test.Student with modifiers "private"
        at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
        at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
        at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
        at java.lang.reflect.Field.set(Field.java:761)
        at cn.ll.test.Test.main(Test.java:17)
 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值