javaSE学习——反射

目录

一、反射的概念

二、获取全类名的三种方式

三、反射获取成员变量的方法

1.getFields(); 获取公共属性数组

2.getField(String name); 获取指定公共属性(public修饰的)

3.getDeclaredFields(); 获取所有属性

4.getDeclaredField(String name); 获取指定属性(不限制修饰符)

五、反射获取成员方法的方法

(一)获取Person类成员方法

1.getMethods(); 返回所有公共成员方法(有参无参都可以)

2.getMethod(String name); 返回指定的公共无参成员方法

3.getDeclaredMethods();  返回所有无参成员方法(不限制修饰符)

4.getDeclaredMethod(String name); 返回指定的无参成员方法(不限制修饰符)

(二)获取Person类构造方法

1.getConstructors(); 返回公共无参构造方法数组

2.getConstructor()+newInstance(); 返回指定的公共构造方法+无参构造实例化

3.getConstructor(new Class[]{parameterTypes})+newInstance();

   返回指定的公共有参构造方法+有参构造方法实例化

4.指定成员方法实例化:invoke(Object obj,Object... args); 

5.反射访问get方法

 6.反射访问set方法


一、反射的概念

        Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。

        加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。

二、获取全类名的三种方式

try {
     Class c = Class.forName("com.atguigu.practices.reflection.Student");
     System.out.println(c);
 } catch (ClassNotFoundException e) {
    e.printStackTrace();
}
Student student = new Student();
Class c2 = student.getClass();
System.out.println(c2);
Class<Student> c3 = Student.class;
System.out.println(c3);

三、反射获取成员变量的方法

先创建一个Person类

package com.atguigu.practices.reflection;

public class Person {
    private String name;
    private Integer age;
    public String gender;
    public String address;
    Integer score;
    protected Boolean Chinese;

    public Boolean getChinese() {
        return Chinese;
    }

    public void setChinese(Boolean chinese) {
        Chinese = chinese;
    }

    public void showInfo(){
        System.out.println(this.getName()+","+this.getAge()+","+this.getGender());
    }

    public void showInfo2(){
        System.out.println(this.getScore()+","+this.getAddress()+","+this.getChinese());
    }

    private void printSecr(){
        System.out.println("私有方法");
    }

    public Person() {
    }

    public Person(Integer score, String address,Boolean Chinese) {
        this.score = score;
        this.address = address;
        this.Chinese = Chinese;
    }

    public Person(String name, Integer age, String gender){
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                ", score=" + score +
                ", address='" + address + '\'' +
                '}';
    }

    public String getName() {
        System.out.println("getName:"+name);
        return name;
    }

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

    private Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        System.out.println("setAge:"+age);
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public boolean isChinese() {
        return Chinese;
    }

    public void setChinese(boolean chinese) {
        Chinese = chinese;
    }
}
  • getFields(); 获取公共属性数组
  • getField(String name); 获取指定公共属性(public修饰的)
  • getDeclaredFields(); 获取所有属性
  • getDeclaredField(String name); 获取指定属性(不限制修饰符)

1.getFields(); 获取公共属性数组

        Field[] fields = c.getFields();
        for (int i = 0; i < fields.length; i++) {// 遍历存放公共属性的数组
            Field field = fields[i];
            System.out.println(field.getName()+","+field.getType());
            // getName():返回此field对象表示的字段的名称
            // getType():返回该field对象表示的字段的声明类型
            // gender,class java.lang.String
            // 只遍历出了一个属性,说明getFields()只能访问到public修饰的属性及其对应的数据类型
        }
           /**
            * 控制台输出:
            * gender,class java.lang.String
            * address,class java.lang.String
            */

2.getField(String name); 获取指定公共属性(public修饰的)

       try {
            Field age = c.getField("address");
            System.out.println(age);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        /**
        * 控制台输出:
        * public java.lang.String com.atguigu.practices.reflection.Person.address
        */

3.getDeclaredFields(); 获取所有属性

fields = c.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
System.out.println(field.getName()+","+field.getType());
// 可以遍历出所有属性及其对应的数据类型
}
 /**
 * 控制台输出:
 * name,class java.lang.String
 * age,class java.lang.Integer
 * gender,class java.lang.String
 * score,class java.lang.Integer
 * address,class java.lang.String
 */

4.getDeclaredField(String name); 获取指定属性(不限制修饰符)

try {
    Field field = c.getDeclaredField("address");
    System.out.println(field.getName()+","+field.getType());
} catch (NoSuchFieldException e) {
  e.printStackTrace();
}
 /**
 * 控制台输出:
 * gender,class java.lang.String
 */

五、反射获取成员方法的方法

(一)获取Person类成员方法

  • getMethods(); 返回所有公共成员方法
  • getMethod(String name, Class<?>... parameterTypes)); 返回指定的公共成员方法

                参数:name–方法的名称;parameterTypes–参数列表

  • getDeclaredMethods();  返回所有成员方法(不限制修饰符)
  • getDeclaredMethod(String name); 返回指定的成员方法(不限制修饰符)

1.getMethods(); 返回所有公共成员方法(有参无参都可以)

Method[] methods = c.getMethods();
        // foreach遍历成员方法数组
        for (Method method :
                methods) {
            System.out.println(method.getName() + "," + method.isVarArgs());
        }
            /**
             * method.getName()方法:
             * 返回此method对象表示的方法的名称(字符串)。
             * method.isVarArgs()方法:
             * 如果此可执行文件声明为采用可变数量的参数,则返回true;否则返回false。
             */

            // 控制台输出:
        /**
         * 返回Person类中所有public修饰的成员方法[数组]
         * toString,false
         * getAddress,false
         * getName,false
         * setName,false
         * setAge,false
         * setChinese,false
         * setChinese,false
         * showInfo2,false
         * setGender,false
         * getGender,false
         * getScore,false
         * setScore,false
         * getChinese,false
         * setAddress,false
         * showInfo,false
         * isChinese,false
         * wait,false
         * wait,false
         * wait,false
         * equals,false
         * hashCode,false
         * getClass,false
         * notify,false
         * notifyAll,false
         */

2.getMethod(String name); 返回指定的公共无参成员方法

try {
                Method showInfoMethod = c.getMethod("showInfo");// 无参
                Method setAgeMethod = c.getMethod("setAge",Integer.class);// 有参
                System.out.println(showInfoMethod);
                System.out.println(setAgeMethod);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        /**
         * public void com.atguigu.practices.reflection.Person.showInfo()
         * public void com.atguigu.practices.reflection.Person.setAge(java.lang.Integer)
         */

3.getDeclaredMethods();  返回所有无参成员方法(不限制修饰符)

Method[] methods1 = c.getDeclaredMethods();
            // for循环遍历
            for (int i = 0; i < methods1.length; i++) {
                Method m2 = methods1[i];
                System.out.println(m2.getName() + "," + m2.isVarArgs());
            }
            
        /**
         * 返回Person类中所有的成员方法[数组]
         * toString,false
         * getAddress,false
         * getName,false
         * setName,false
         * setAge,false
         * setChinese,false
         * setChinese,false
         * showInfo2,false
         * printSecr,false
         * getAge,false
         * setGender,false
         * getGender,false
         * getScore,false
         * setScore,false
         * getChinese,false
         * setAddress,false
         * showInfo,false
         * isChinese,false
         */

4.getDeclaredMethod(String name); 返回指定的无参成员方法(不限制修饰符)

try {
                Method printSecrMethod = c.getDeclaredMethod("printSecr");
                Method getNameMethod = c.getDeclaredMethod("setName",String.class);
                System.out.println(printSecrMethod);
                System.out.println(getNameMethod);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            // 控制台输出:
            /**
             * 返回任意无参成员方法,不限制修饰符
             * private void com.atguigu.practices.reflection.Person.printSecr()
             * private void com.atguigu.practices.reflection.Person.setName(java.lang.String)
             */

(二)获取Person类构造方法

  • getConstructors(); 返回公共构造方法数组(不限制参数)
  • getConstructor(new Class[]{parameterTypes}); 返回指定的公共构造方法
  • getConstructor(); 返回公共无参构造
  • newInstance(); 使用此构造函数对象表示的构造函数,使用指定的初始化参数创建和初始化构造函数声明类的新实例。单个参数会自动展开以匹配原始形式参数,并且原始参数和引用参数都会根据需要进行方法调用转换。
  • invoke(Object obj,Object... args);  在具有指定参数的指定对象上调用此method对象表示的基础方法。单个参数会自动展开以匹配原始形式参数,并且原始参数和引用参数都会根据需要进行方法调用转换。
  • obj–调用基础方法的对象;args–用于方法调用的参数

1.getConstructors(); 返回公共无参构造方法数组

Constructor[] constructors = c.getConstructors();
for (int i = 0; i < constructors.length; i++) {
    Constructor constructor = constructors[i];
    System.out.println(constructor.getName());
}
/**
* com.atguigu.practices.reflection.Person
* com.atguigu.practices.reflection.Person
* com.atguigu.practices.reflection.Person
*/

2.getConstructor()+newInstance(); 返回指定的公共构造方法+无参构造实例化

    parameterTypes参数是一个Class对象数组,以声明的顺序标识构造函数的形式参数类型

try {
            Constructor constructor = c.getConstructor();
            System.out.println(constructor.getName());
            //com.atguigu.practices.reflection.Person

            // 无参构造方法初始化
            Object obj = constructor.newInstance();
            System.out.println(obj);
            //Person{name='null', age=null, gender='null', score=null, address='null'}

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

3.getConstructor(new Class[]{parameterTypes})+newInstance();

   返回指定的公共有参构造方法+有参构造方法实例化

   parameterTypes参数是一个Class对象数组,以声明的顺序标识构造函数的形式参数类型。

try {
            Constructor constructor = c.getConstructor(new Class[]{String.class, Integer.class, String.class});
            System.out.println(constructor.getName());
            // com.atguigu.practices.reflection.Person

            // 有参构造初始化
            Object obj = constructor.newInstance("zhangsan", 45, "男");
            System.out.println(obj);
            // Person{name='zhangsan', age=45, gender='男', score=null, address='null'}

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

4.指定成员方法实例化:invoke(Object obj,Object... args); 

try {
            Method method = c.getDeclaredMethod("showInfo2");
            Object obj1 = c.getConstructor().newInstance();// 未传参
            Constructor constructor = c.getConstructor(new Class[]{Integer.class, String.class, Boolean.class});
            Object obj = constructor.newInstance(new Object[]{100,"上海路20号", true});// 传参
            Object invoke = method.invoke(obj1,null);
            // null,null,null
            Object invoke2 = method.invoke(obj,null);
            // 100,上海路20号,true
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }

5.反射访问get方法

try {
            // 找到方法后,即使传递很多参数也会自动匹配,前提是n个参数也能够自动匹配到类中的有参构造方法
            Method getNameMethod = c.getDeclaredMethod("getName");
            Constructor constructor = c.getConstructor(new Class[]{String.class,Integer.class,String.class});
            Object obj = constructor.newInstance(new Object[]{"张三",20,"男"});
            getNameMethod.invoke(obj,null);
            // getName:张三
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

 6.反射访问set方法

try {
            // 基于字节码对象获取类的构造方法对象
            Constructor con = c.getConstructor();
            // 构建类的实例对象
            Object obj = con.newInstance();
            Method m=c.getDeclaredMethod("setName",String.class);
            m.invoke(obj,"张三");
            System.out.println(obj);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        // Person{name='张三', age=null, gender='null', score=null, address='null'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值