反射

内容简介:

  1. 反射的概念
  2. 使用反射操作类成员的前提
  3. 反射在实际开发中的应用
  4. Class对象的三种获取方式
  5. Class类常用方法
  6. 反射之操作构造方法
  7. 反射之操作成员方法
  8. 反射之操作成员变量
  9. 反射操作的Student实体类代码
反射的概念:
  • 反射是一种机制,利用该机制可以在程序的运行过程中对类进行解剖并操作类中的所有成员: 构造方法,成员变量,成员方法等。
使用反射操作类成员的前提:
  • 必须要获得类的字节码文件对象,即是Class对象
反射在实际开发中的应用:
  • 开发IDE(集成开发环境,比如Eclipse,IDEA…)
  • 各种框架的设计,比如Hibernate,Spring,Struct 简称:SSH
Class对象的三种获取方式:
/**
    获得Class对象的三种方式
        * 方式1:通过对象名调用getClass方法获得
        * 方式2:直接通过类名.class获得
        * 方法3:通过Class类的静态方法获得:static Class forName("类全名字符串");
    以上三种方式获得的Class对象都是相同的。
 */
public class ReflectDemo01 {
    public static void main(String[] args) throws ClassNotFoundException {
        // 创建字符串
        String str = "HelloWorld";
        // 获得字符串的Class对象
        Class c1= str.getClass();
        // 直接通过类名.class获得
        Class c2 =  String.class;
        // 通过Class类的静态方法获得:static Class forName("类全名字符串");
        Class c3 = Class.forName("java.lang.String");
        System.out.println(c1 == c2);
        System.out.println(c1 == c3);
        System.out.println(c2 == c3);
    }
}

这里写图片描述

Class类常用方法:
/**
    Class类常用方法
         String getSimpleName(); 获得类名字符串
         String getName(); 获得类全名字符串
         T newInstance() ; 创建对象,类必须有public修饰的无参数构造方法。
 */
public class ReflectDemo02 {
    public static void main(String[] args) throws Exception, InstantiationException {
        // 直接通过类名.class获得
        Class<Student>  c =  Student.class;
​
        System.out.println(c.getSimpleName()); // Student
        System.out.println(c.getName()); // com.itheima._03反射.Student// 创建学生对象
        Student stu =   c.newInstance();
​
        System.out.println(stu);
    }
}
反射之操作构造方法:
/**
    构造方法概述
        * 每一个类中的构造方法都是一个Constructor类的对象。
        * 获得构造方法对象的目的就是要利用构造方法对象创建对象。
​
    Class类中与Method相关的方法
         1. Constructor getConstructor(Class... parameterTypes)
            * 根据指定参数类型获得对应的构造方法对象,只能获得public修饰的方法
         2. Constructor getDeclaredConstructor(Class... parameterTypes)
            *  根据指定参数类型获得对应的构造方法对象,包括private修饰
         3. Constructor[] getConstructors()
            * 获得所有的构造方法对象,只能获得public修饰的
         4. Constructor[] getDeclaredConstructors()
            * 获得所有的构造方法对象,包括private修饰的
​
    Constructor类成员方法
        *  T newInstance(Object... initargs)
            * 根据指定参数来创建对象
        *  void setAccessible(true)
            * 设置是否取消权限检查,true表示取消,false表示不取消。
            * 暴力反射
 */
public class ReflectDemo03 {
    // Constructor[] getConstructors(); 获得所有的构造方法对象,只能获得public修饰的
    // Constructor[] getDeclaredConstructors(); 获得所有的构造方法对象,包括private修饰的
    @Test
    public void test03()throws Exception{
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 获得所有的构造方法对象,只能获得public修饰的,返回数组
        // Constructor[] cons = c.getConstructors();
        // 获得所有的构造方法对象,包括private修饰的,返回数组
        Constructor[] cons = c.getDeclaredConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
    }
​
    // Constructor getDeclaredConstructor(Class... parameterTypes)
    @Test
    public  void test02() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 获得一个参数的构造方法对象
        Constructor con = c.getDeclaredConstructor(String.class);
        // 设置取消权限检查(暴力反射)
        con.setAccessible(true);
        // 创建学生对象
        Object stu = con.newInstance("rose");
        System.out.println(stu);
    }
​
    // Constructor getConstructor(Class... parameterTypes)
    @Test
    public  void test01() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 获得两个参数的构造方法对象
        // public com.itheima._03反射.Student(java.lang.String,int)
        Constructor con = c.getConstructor(String.class,int.class);
        System.out.println(con);
        // 创建学生对象
        Student stu = (Student) con.newInstance("jack",20);
        System.out.println(stu);
​
        // 获得无参数构造方法对象
        Constructor con02 = c.getConstructor();
        // 创建学生对象
        Student stu02 = (Student) con02.newInstance();
        System.out.println(stu02);
    }
}

这里写图片描述

反射之操作成员方法:
/**
    成员方法概述
        * 每一个类中的成员方法都是一个Method类的对象。
        * 获得Method对象的目的就是要调用该方法
​
    Class类中与Method相关的方法
        * Method getMethod(String methodName, Class...args)
            * 根据方法名和参数类型获得对应的Method对象,只能获得public修饰的
        * Method getDeclaredMethod(String methodName, Class...args)
            * 根据方法名和参数类型获得对应的Method对象,包括private修饰的
​
        * Method[] getMethods()
            * 获得类中的所有的成员方法对象,只能获得public的,包括父类的
        * Method[] getDeclaredMethods()
            * 获得类中的所有的成员方法对象,只能获得本类的,包括private
​
​
    Method类成员方法
         * Object invoke(Object obj, Object... args)
            * 调用obj对象的该方法,args:调用方法传递的参数
            * 返回值是Object
​
         2. void setAccessible(boolean flag)
            * 设置是否取消权限检查,true表示取消,false表示不取消。
            * 暴力反射
 */
public class ReflectDemo04 {
    /*
        反射获得类中所有的成员方法对象
    */
    @Test
    public void test04() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        //  获得类中所有的成员方法对象
        // Method[] methods = c.getMethods();
        Method[] methods = c.getDeclaredMethods();
        for (Method m:methods) {
            System.out.println(m);
        }
    }
​
​
    /*
     反射操作private修饰的成员方法
     */
    @Test
    public void test03() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 创建学生对象
        Object stu = c.newInstance();
        // 获得study方法对应的Method对象
        Method studyMethod = c.getDeclaredMethod("study",int.class);
        // 暴力反射
        studyMethod.setAccessible(true);
        // 调用study方法
        studyMethod.invoke(stu,20);
    }
​
​
    /*
     反射操作public修饰的静态方法
     */
    @Test
    public  void test02() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 获得eat方法对应的Method对象
        Method eatMethod = c.getMethod("eat",String.class);
        // 调用eat方法
        eatMethod.invoke(null,"蛋蛋");
    }
​
    /*
     反射操作public修饰的方法
     */
    @Test
    public  void test01() throws Exception {
        // 获得Student类的Class对象
        Class c = Class.forName("com.itheima._03反射.Student");
        // 创建学生对象
        Object stu = c.newInstance();
        // 获得study方法对应的Method对象
        Method studyMethod = c.getMethod("study");
        // 调用stu对象的study方法
        studyMethod.invoke(stu);
    }
}

这里写图片描述

反射之操作成员变量:
/**
    成员变量概述
        * 每一个成员变量都是一个Field类的对象,通过Field对象可以给成员变量赋值和取值。
​
    Class类与Field相关的方法
        * Field getField(String name);
        * Field getDeclaredField(String name);
        * Field[] getFields();
        * Field[] getDeclaredFields();
​
    Field类成员方法
         void  set(Object obj, Object value)
         void setInt(Object obj, int i)
         void setLong(Object obj, long l)
         void setBoolean(Object obj, boolean z)
         void setDouble(Object obj, double d)
​
         Object get(Object obj)
         int    getInt(Object obj)
         long getLong(Object obj)
         boolean getBoolean(Object ob)
         double getDouble(Object obj)
​
         void setAccessible(true);暴力反射,设置为可以直接访问私有类型的属性。
         Class getType(); 获取属性的类型,返回Class对象。
 */
public class ReflectDemo05 {
    /*
       反射获得类中的所有成员变量对象
     */
    @Test
    public void test04() throws Exception {
        // 获得Class对象
        Class c = Student.class;
        // 获得类中的所有成员变量对象,只能获取public的
        // Field[] fs = c.getFields();
        //  获得类中的所有成员变量对象,包含private的
        Field[] fs = c.getDeclaredFields();
        for (Field f:fs) {
            System.out.println(f);
        }
    }
​
    /*
       反射操作静态成员变量
     */
    @Test
    public void test03() throws Exception {
        // 获得Class对象
        Class c = Student.class;
        // 根据成员变量名获得对应的Field对象
        Field f = c.getDeclaredField("address");
        // 暴力反射
        f.setAccessible(true);
        // 给静态成员变量赋值
        f.set(null,"东莞");
​
        System.out.println(f.get(null));
    }
​
    /*
       反射操作private修饰的成员变量
     */
    @Test
    public void test02() throws Exception {
        // 获得Class对象
        Class c = Student.class;
        // 创建学生对象
        Object stu = c.newInstance();
        // 根据成员变量名获得对应的Field对象
        Field f = c.getDeclaredField("name");
        // 暴力反射
        f.setAccessible(true);
        // 给成员变量赋值
        f.set(stu,"jack");
​
        System.out.println(stu);
    }
​
    /*
       反射操作public修饰的成员变量
     */
    @Test
    public void test01() throws Exception {
        // 获得Class对象
        Class c = Student.class;
​
        // 创建学生对象
        Object stu = c.newInstance();
​
        // 根据成员变量名获得对应的Field对象
        Field f = c.getField("gender");
        // 给成员变量赋值
        f.set(stu,"男");
​
        // 根据成员变量age获得对应的Field对象
        Field ageField = c.getField("age");
​
        // ageField.setInt(stu,20);
        ageField.set(stu,"30");
        // 获得成员变量的值
        Object gender = f.get(stu);
        System.out.println(gender); // 男
        System.out.println(ageField.get(stu));// 20
    }
}

这里写图片描述

Student实体类代码:
public class Student {
    private static String address;  // private修饰的私有的静态的地址
    public String gender;  //public修饰的公开性别
    private String name;  //private修饰的私有名字
    public Integer age;  //public修饰的公开年龄

    public Student(String name, int age) {
        System.out.println("两个参数的构造方法");
        this.name = name;
        this.age = age;
    }

    public Student() {
        System.out.println("无参数构造方法");
    }

    private Student(String name){
        System.out.println("一个参数构造方法");
        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 void study(){
        System.out.println("好好学习,天天向上");
    }

    private void study(int hour){
        System.out.println("好好学习,天天向上 = " + hour);
    }

    public static void eat(){
        System.out.println("好好吃,好好睡");
    }


    public static void eat(String name){
        System.out.println("好好吃,好好睡 " + name);
    }

    @Override
    public String toString() {
        return "Student{" +
                "gender='" + gender + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值