反射常用操作(奥里给!)

  1. 反射概述
    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;同时也能调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
    我们通过一个类的字节码文件获取到他的所有信息。

 

 (图->itheima)

2.反射的常用操作

1.获取Class对象(反射永远的第一步操作)

2.反射调用对象中的成员方法

3.反射调用对象中的构造方法

4.反射调用对象中的属性

在此之前定义一个student类

 

public class Student {
    private String name;
    Integer age;
    public String address;

    public Student(){}
    public Student(String name,Integer age,String address){
        this.name=name;
        this.age=age;
        this.address=address;
    }
    private Student(String name){
        this.name=name;
    }
    Student(String name,Integer age){
        this.name=name;
        this.age=age;
    }

    private void function(){
        System.out.println("function");
    }
    public void method1(){
        System.out.println("method");
    }

    public void method2(String s){
        System.out.println("method:"+s);
    }
    public String method3(String s, Integer i){
        return s+","+i;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}
  •  获取Class对象

三种方法可以获得Class

1.使用类的Class属性来获取该类对应的Class对象。

2.调用Object的getClass()方法,返回该对象所属类对应的Class对象

3.使用Class类中的静态方法forName(String className) 该方法的参数,该字符串参数的值  是某个类的全路径

第三种是最为推荐的

直接上代码:

 //使用类的Class属性来获取该类对应的Class对象。
        //.class是字节码文件
        Class<Student> student = Student.class;
        Class<Student> student1=Student.class;
        System.out.println(student);
        System.out.println(student==student1);

        //调用对象的getClass()方法,返回该对象所属类对应的Class对象
        Student student2=new Student();
        Class<? extends Student> student21 = student2.getClass();

        System.out.println(student21==student);
        //使用Class类中的静态方法forName(String className)  该方法的参数,该字符串参数的值是某个类的全路径
        Class<?> student3 = Class.forName("com.ReflectTest.Student");
        System.out.println(student3==student);

结果:

 所以一个类的Class对象是相同的,因为他们的字节码文件是唯一的

 

  • 反射调用对象中的成员变量

1.getDeclaredField(参数)   返回某一个成员变量

2.getFields()   返回所有公开的成员变量  返回类型为数组

3.getField()    返回某一个公开的成员变量  

4.getDeclaredFields(参数) 返回所有的成员变量  返回类型为数组

(同下,大家都是聪明人就不一一测试了)

         //获取Class类
        Class<?> student = Class.forName("com.ReflectTest.Student");
        //获取一个公共的成员变量
        Field field = student.getField("address");
        //给address赋值
        //1.获取对象
        Constructor<?> con = student.getConstructor();
        //2.初始化实例
        Object o = con.newInstance();
        //3.使用field对象赋值
        field.set(o,"武汉");
        System.out.println(o);

 

  • 反射调用对象中的构造方法

1.getDeclaredConstructor(参数)  返回某一个构造方法

2.getConstructors()   返回所有公开的构造方法  返回类型为数组

3.getConstructor()    返回某一个公开的构造方法  

4.getDeclaredConstructors(参数) 返回所有的构造方法  返回类型为数组

直接上代码:

        //获取Class对象 Declared是所有的  没有Declared为公共的
        Class<?>student=Class.forName("com.ReflectTest.Student");

        //getConstructor(类<?>... parameterTypes)  返回一个 Constructor对象,返回单个公共构造方法对象
        //newInstance(Object... initargs) 使用此 Constructor对象表示的构造函数,使用指定的初始化参数来创建和初始化构造函数的声明类的新实例。
        //根据Constructor创建con1(带三个参数的公共构造方法对象)
        Constructor<?> con1 = student.getConstructor(String.class, Integer.class, String.class);
        Object o = con1.newInstance("猪猪侠",17,"弗洛伊德");
        System.out.println(o);

        System.out.println(con1);
        System.out.println("---");

        //getConstructors()  返回包含一个数组 Constructor对象,返回所有公共构造方法对象的数组
        Constructor<?>[] con2 = student.getConstructors();
        for (Constructor con : con2) {
            System.out.println(con);
        }
        System.out.println("---");

        //getDeclaredConstructor(类<?>... parameterTypes)  返回一个 Constructor对象,返回单个构造方法对象
        Constructor<?> con3 = student.getDeclaredConstructor();
        System.out.println(con3);
        System.out.println("---");

        //getDeclaredConstructors() 返回一个反映 Constructor对象,返回所有构造方法对象的数组
        Constructor<?>[] con4 = student.getDeclaredConstructors();
        for (Constructor con : con4) {
            System.out.println(con);
        }

结果:

反射构造对象时 需初始化newInstance

若构造方法为私有的,还需要调用setAccessible(true)来取消访问检查

        //获取Class类
        Class<?>student=Class.forName("com.ReflectTest.Student");
        //反射获取一个private方法的反射对象
        Constructor<?> con = student.getDeclaredConstructor(String.class);
        //private的构造方法无法创建对象  需要赋予权限
        //setAccessible 值为true 取消访问检查
        //newInstance 初始化实例
        con.setAccessible(true);
        Object o = con.newInstance("林青霞");
        System.out.println(o);

 

  • 反射调用对象中的成员方法

同上 方法改为

1.getDeclaredMethod(参数)  返回某一个成员方法

2.....  3....  4....

//获取Class字节码文件
        Class<?> pra = Class.forName("com.ReflectTest.Student");
        //1.反射获得student对象
        Constructor<?> con = pra.getDeclaredConstructor();
        //2.对象的初始化
        Object o = con.newInstance();
        //3.通过对象调用method1方法
        //先反射获得method1方法
        Method method1 = pra.getDeclaredMethod("method1");
        method1.invoke(o);
        System.out.println("-----");
        //4.通过对象调用method2方法
        Method method2 = pra.getDeclaredMethod("method2", String.class);
        method2.invoke(o,"林青霞");
        System.out.println("-----");

 

see you! 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值