【java基础】反射-Reflect相关知识

【java基础】反射简述

一、概述

1.简介

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

或者这样说,将类的的各个组成部分封装成其他对象。(画图解释)
java代码三个阶段

Java代码在计算机中经历三个阶段:

  1. 源代码阶段 Source
  2. 类对象阶段 Class
  3. 运行时阶段 Runtime

反射也就是把字节码文件中的成员方法封装成成员方法的对象,构造方法封装成构造方法对象,成员方法封装成成员方法对象。(由于不止一个,所以是数组的形式) → 也就是将类的的各个组成部分封装成其他对象。(反射)

那这样封装,有什么用处呢?或者什么好处呢?

2.用途(好处)
  • 可以在程序运行过程中,操作这些对象
  • 可以解耦,提高程序的可扩展性

二、反射的 API 1

在JDK中,主要由以下类来实现Java反射机制,这些类(除了第一个)都位于java.lang.reflect包中

Class类:代表一个类,位于java.lang包下。

Field类:代表类的成员变量(成员变量也称为类的属性)。

Method类:代表类的方法。

Constructor类:代表类的构造方法。

Array类:提供了动态创建数组,以及访问数组的元素的静态方法。

要想使用反射,首先需要获得待操作的类所对应的Class对象。

三、Class对象

获取类所对应的Class对象共有三种方式,分别对应图上的三个阶段

  1. Class.forName(“全类名”):将字节码文件加入内存,返回Class对象
    • 用途:多用于配置文件
  2. 类名.class:通过类名的属性class来获取
    • 用途:多用于参数的传递
  3. 对象.getClass():getClass()方法在Object类定义着。
    • 用途:多用于对象获取字节码的方式

结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次

也就是说,不论上面哪三种方法获取Class对象,都是同一个对象。

四、使用Class对象

1.获取功能
  • 获取成员变量们 Feild
方法名说明
Field getField(String name)获取指定名称的public修饰的成员变量
Field[] getFields()获取所有public修饰的成员变量
Field getDeclaredField(String name)获取指定名称的成员变量,不考虑修饰符
Field[] getDeclaredFieldFields()获取所有的成员变量,不考虑修饰符
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        //0.获取Person的Class对象
        Class pClazz = Person.class;
        /**
         * 1.获取成员变量们
         *  * Field[] fields
         *  *
         */
        Field[] fields = pClazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        //获取成员变量apple
        Field a = pClazz.getField("apple");
        System.out.println(a);

        //设置成员变量apple的值
        Person person = new Person();
        a.set(person,"Change the World");
        //获取apple的值
        Object o = a.get(person);
        System.out.println(o);

        System.out.println("********************************************");

        //获取所有的成员变量不考虑修饰符
        Field[] fields2 = pClazz.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }
        //获取成员变量dee(私有)
        Field dee = pClazz.getDeclaredField("dee");
        //忽略访问权限修饰符(暴力反射) = 我的是我的,你的还是我的
        dee.setAccessible(true);
        //获取值
        Object deeValue = dee.get(person);
        System.out.println(deeValue);//因为没赋值 所以是null
    }
}

public class Person {
    private String name;
    private int age;
    //不同修饰符
    public String apple;
    protected String banana;
    String cow;
    private String dee;

    public Person() {
    }
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void sleep(){
        System.out.println("zzzZZZZ~");
    }
    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 eat(String food){
        System.out.println(food);
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", apple='" + apple + '\'' +
                ", banana='" + banana + '\'' +
                ", cow='" + cow + '\'' +
                ", dee='" + dee + '\'' +
                '}';
    }
}

结果:

public java.lang.String com.cz.reflect.Person.apple
public java.lang.String com.cz.reflect.Person.apple
Change the World
********************************************
private java.lang.String com.cz.reflect.Person.name
private int com.cz.reflect.Person.age
public java.lang.String com.cz.reflect.Person.apple
protected java.lang.String com.cz.reflect.Person.banana
java.lang.String com.cz.reflect.Person.cow
private java.lang.String com.cz.reflect.Person.dee
null
  • 获取构造方法们
方法名说明
Constructor getConstructor(类... parameterTypes)获取类中与参数类型匹配的公有构造方法
Constructor[] getConstructors()获得该类的所有公有构造方法
Constructor getDeclaredConstructor(类... parameterTypes)获得该类中与参数类型匹配的构造方法
Constructor[] getDeclaredConstructors()获得该类所有构造方法
public class ReflectConstructors {
    public static void main(String[] args) throws Exception {
        //0.获取Person的Class对象
        Class pClazz = Person.class;
        /**
         * 2.获取构造方法们
         *  *
         *  *
         */
        //获取所有公共类的构造方法
        Constructor[] constructors = pClazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("*******************************************");
        //指定名称的构造方法
        Constructor constructor = pClazz.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //构造器用来创建对象
        Object person = constructor.newInstance("李白", 23);
        System.out.println(person);

        System.out.println("_____________空参操作对象可以简化________________________");
        Constructor constructorNull = pClazz.getConstructor();
        Object person2 = constructorNull.newInstance();
        System.out.println(person2);

        System.out.println("_____________简化后________________________");
        Object person3 = pClazz.newInstance();
        System.out.println(person3);//一步到位

        //Declared同上面不做演示

    }
}

结果:

public com.cz.entity.Person()
public com.cz.entity.Person(java.lang.String,int)
*******************************************
public com.cz.entity.Person(java.lang.String,int)
com.cz.entity.Person@3c679bde
_____________空参操作对象可以简化________________________
com.cz.entity.Person@16b4a017
_____________简化后________________________
com.cz.entity.Person@8807e25
  • 获取成员方法们
方法名说明
Method getMethod(String name, 类... parameterTypes)获得该类某个公有的方法
Method[] getConstructors()获得该类所有公有的方法
Method getDeclaredMethod(String name, 类... parameterTypes)获得该类某个方法
Method[] getDeclaredMethods()获得该类所有方法
public class ReflectMethods {
    public static void main(String[] args) throws Exception {
        //0.获取Person的Class对象
        Class pClazz = Person.class;
        /**
         * 3.获取成员方法们
         *  *
         *  *
         */
        //获取指定名称的成员方法(public)
        Method method = pClazz.getMethod("sleep");
        Person person = new Person();
        //执行方法
        method.invoke(person);

        //现在在Person里加个方法
        Method eat = pClazz.getMethod("eat", String.class);
        //执行方法
        eat.invoke(person,"苹果");

        System.out.println("------------------------------------------");
        /*获取所有公共(public)方法  这里还有Object的方法*/
        Method[] methods = pClazz.getMethods();
        for (Method method1 : methods) {
            System.out.println(method1);
        }
        System.out.println();
        Method[] methods2 = pClazz.getDeclaredMethods();
        for (Method method1 : methods2) {
            //忽略修饰符,暴力反射
            method1.setAccessible(true);
            System.out.println(method1);
            System.out.println(method1.getName());//获取方法名
        }

    }
}

结果:

zzzZZZZ~
苹果
------------------------------------------
public java.lang.String com.cz.entity.Person.toString()
public java.lang.String com.cz.entity.Person.getName()
public void com.cz.entity.Person.setName(java.lang.String)
public void com.cz.entity.Person.sleep()
public void com.cz.entity.Person.eat(java.lang.String)
public int com.cz.entity.Person.getAge()
public void com.cz.entity.Person.setAge(int)
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

public java.lang.String com.cz.entity.Person.toString()
toString
public java.lang.String com.cz.entity.Person.getName()
getName
public void com.cz.entity.Person.setName(java.lang.String)
setName
public void com.cz.entity.Person.sleep()
sleep
public void com.cz.entity.Person.eat(java.lang.String)
eat
public int com.cz.entity.Person.getAge()
getAge
public void com.cz.entity.Person.setAge(int)
setAge

  1. Java 反射机制 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值