Java学习笔记12-反射

1、简介

        Java的反射机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。即:在程序运行过程中分析类的一种能力(通过访问字节码.class文件,创建并使用对象的过程)

2、特点

  • 对于任意一个类,都能够知道这个类的所有属性和方法
  • 对于任意一个类,都能够调用它的任意一个属性和方法

3、功能

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

4、用法

获取类Class对象

1、类加载器:将类的字节码文件(.class)加载到内存中,并生成对应的Class对象。每个Class对象对应一个字节码文件。

2、作用

在运行时通过反射获取类的Class对象

3、获取类Class对象常用方法

  • 根据对象获取:
    Class clazz=对象名.getClass();
  • 根据类名获取:
    Class clazz=类名.class;
  • 根据类名字符串获取:
    Class clazz.forName(“类的正名”); 正名:包类的路径名

类对象:

public class Person {

    private String name;
    public int age;
    public int money;

    public Person() {
    }

    public Person(String name, int age) {
        System.out.println("有参构造器");
        this.name = name;
        this.age = age;
    }
    private Person(int age) {

        this.age = age;
    }

    public void info(){
        System.out.println("无参方法");
    }

    private void info(String name){
        System.out.println("无参方法");
        System.out.println("你的名字是:"+name);
    }

    public void info(int age){
        System.out.println("有参方法");
        System.out.println("今年年龄是:"+age);
    }


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

获取Class对象:

public class ObjectText {

    public static void main(String[] args) throws Exception {

        //获取Class对象
        //方法一
        Class clazz1=Class.forName("cn.reflection.Person");
        System.out.println(clazz1);

        //方法二
        Person person=new Person();
        Class clazz2=person.getClass();
        System.out.println(clazz2);
        //方法三
        Class clazz3=Person.class;
        System.out.println(clazz3);
    }
}

构造方法Constructor

1、作用
通过反射获取类的构造器

2、获取构造器对象

  • getConstructor(Class<?>… parameterTypes)返回一个仅公共的构造方法
  • getDeclaredContructor(Class<?>…parameterTypes) 返回一个私有的构造方法
  • getConstructors()返回类所有的构造方法(不含私有)

3、常用方法

  • String getName() 返回构造方法名
  • T newInstance(Object…intargs) 使用此后构造方法创建并初始化对象(T向下转型)
public class ConstructorText {

    public static void main(String[] args) throws Exception {
        //1.获取对象
        Class clazz=Class.forName("cn.reflection.Person");
        //2.获取构造器
        //无参构造
        Constructor constructor1 = clazz.getConstructor();

        String name1 = constructor1.getName();
        System.out.println(name1);
         //有参构造
        Constructor constructor2 = clazz.getConstructor(String.class, int.class);
        System.out.println(constructor2);
        //私有的有参构造
        Constructor constructor3 = clazz.getDeclaredConstructor(int.class);
        System.out.println(constructor3);

        //获取所有的所有的构造器,除私有的
        Constructor[] constructor4 = clazz.getConstructors();
        System.out.println(constructor4);

        //3.创建初始化对象并输出,向下转型
        Person person=(Person)constructor2.newInstance("zhangsan",22);
        System.out.println(person);

    }
}
成员方法Method

1、作用
通过反射获取类的成员方法

2、获取对象

  • getMethod(String name,Class…parameterTypes)返回公共的成员方法
    name:方法名;parameterTypes:方法的参数列表
  • getDeclaredMethod(String,Class<?>)返回私有的成员方法
  • getMethod()返回此类所有(不含私有)方法的数组

3、常用方法

  • String getName() 返回方法名
  • Object invoke(Object obj,Object…args)在指定对象上调用此方法,参数为args
  • setAccessible(true);开启暴力反射,用于调用私有带参方法
public class MethodText {

    public static void main(String[] args) throws Exception {

        //1.创建反射对象的字节码文件
        Class clazz=Class.forName("cn.reflection.Person");

        //2.获取构造器,创建类的对象
        Constructor constructor = clazz.getConstructor();
        Object newInstance = constructor.newInstance();

        //3.获取方法
        //无参
        Method method1 = clazz.getMethod("info");
        System.out.println(method1.getName());

        //私有有参
        Method info = clazz.getDeclaredMethod("info", String.class);
        System.out.println(info.getName());

        //返回所有共有的方法,不包含私有
        Method[] methods = clazz.getMethods();
        System.out.println(methods);

        for (Object obj:methods){
            System.out.println(obj);
        }


        //4.调用私有方法并赋值
        //开启暴力反射
        info.setAccessible(true);
        //调用此方法
        Person invoke =(Person) info.invoke(newInstance, "小明");
        //打印结果
        System.out.println(invoke);
    }
}
成员变量Field

1、作用
通过反射获取类的成员变量

2、获取对象

  • getField(String name)返回一个公共的属性
  • getDeclaredField(String name)返回一个私有属性
  • getDeclaredFields()返回此类所有(含私有)属性的数组

3、常用方法

  • void set(Object obj,Object value)设置obj对象的指定属性值
  • setAccessible(true);开启暴力反射,用于调用私有带参方法
public class FieldText {

    public static void main(String[] args) throws Exception {
        //1.获取类的字节码文件
        Class clazz = Class.forName("cn.reflection.Person");

        //2.获取构造器,并创建对象
        Constructor constructor = clazz.getDeclaredConstructor(int.class);
        constructor.setAccessible(true);
        Person ins = (Person) constructor.newInstance(12);

        //3.获取变量
        //共有变量
        Field field1 = clazz.getField("age");
        System.out.println(field1);

        //私有变量
        Field field2 = clazz.getDeclaredField("name");
        System.out.println(field2);

        //返回所有变量含私有
        Field[] fields = clazz.getDeclaredFields();
        System.out.println(fields);
        for (Object obj : fields) {
            System.out.println(obj);
        }

        //4.调用变量并赋值
        field2.setAccessible(true);
        field2.set(ins, "小明");

        //打印对象
        System.out.println(ins);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值