反射

反射 顾名思义 就是反着来 正常的类创建是 new出来的 而反射是通过一个实例 去反着得到一个类 。

如果两个实例都是相同的类 new出来的 那个这两个类反射得到的 Class对象 也是一样的。(hashcode相同)

通过反射 我们可以得到这个类中的所有属性(不管是不是private的) 它的所有方法 它的一切 都可以通过反射得到。

创建一个类分为三个步骤 : 加载 链接 初始化

加载: 将Class字节码内容加载到内存中,然后生成一个 java.lang.Class对象

链接:将Java类的二进制代码合并到JVM的运行状态之中的过程。

初始化当初始化一个类的时候 如果它的父类还未被初始化 那么会先初始化它的父类

反射的一些方法 代码如下:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Test{
    public String name;//public类型的属性
    private int id;//private类型的属性

    public Test(){

    }

    public Test(String name,int id){
        this.id = id;
        this.name = name;
    }

    //私有的方法
    private void sayHi(){
        System.out.println("Hi !");
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

public class ReflectDemo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchFieldException {

        Test t1 = new Test("哈宝欣",38);//使用普通的new 方法实例化对象

        Class<?> c1 = Class.forName("Test");

        //获得类的全名
        System.out.println(c1.getName());

        //获得类的所有构造方法(不管是不是private) 如果只想获得公开的构造方法 就使用c1.getConstructors()
        Constructor[] constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }

        //获得类的所有方法(不管是不是private)如果只想获得公开的方法 就使用c1.getMethods()
        Method[] declaredMethods = c1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        //获得类的所有属性
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        //可以使用反射得到的构造方法初始化一个对象
        //首先先获得想要的构造函数
        Constructor test = c1.getDeclaredConstructor(String.class,int.class);
        //使用构造函数的newInstance方法 实例化一个对象
        Test t2 = (Test)test.newInstance("李四",1);
        System.out.println(t2.getName());

        //可以使用反射得到普通方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //使用函数的invoke()  执行这个函数  参数分别是 执行这个函数的对象和传入这个函数的参数
        setName.invoke(t2,"李思思");
        System.out.println(t2.getName());

        //可以通过反射去操作字段
        //获得这个字段属性
        Field id = c1.getDeclaredField("id");
        //操作这个属性
        System.out.println(t2.getId());
        //使用set方法去操作这个属性  参数是操作的对象和传入的参数
        // 注意 如果这个字段是私有的  那么要使用setAccessible方法 把它这设置为可以访问才能修改
        id.setAccessible(true);
        id.set(t2,989);
        System.out.println(t2.getId());
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值