Java - 反射

反射

Java反射是指程序在运行时,能够访问、检测和修改它本身的状态或行为的一种能力。这种能力使得Java代码能够动态地创建、管理和操纵对象,而无需在编译时进行硬编码。

在Java中,反射机制主要通过类、对象、方法和属性的动态访问来实现。利用反射,开发人员可以在运行时动态地调用类的方法、访问和修改对象的属性,从而构建更加灵活和动态的代码。然而,需要注意的是,过度使用反射可能导致代码效率降低和性能问题。

1. 概述

反射技术,指的是加载类的字节码到内存,并以编程的方法解刨出类中的各个成分(成员变量、方法、构造器等)
在这里插入图片描述

2. Java反射中常用的类包括:

Class类:表示一个类,提供了访问类和对象属性的方法,以及获取类方法、构造函数、枚举、注解等的能力。
Method类:表示一个方法,提供了调用方法、获取方法参数、设置方法访问权限等的能力。
Field类:表示一个属性,提供了访问和修改属性值的能力。
Constructor类:表示一个构造函数,提供了创建对象实例的能力。

3. 获得类名(Class)

获取Class对象一共有3种方式
1. 已知类名:User,使用场景:一般在反射声明方法类型时调用。
2. 已知对象:user,使用场景:一般在一个普通方法内,通过变量进行反射操作。
3. 已知全限定类名:xxx.xx.User 字符串,一般用于框架加载类时。

代码实现:
创建User实体类:以下代码通用实体类

package reflect;

public class User {
    // 成员变量
    private String username = "jack";
    public int age = 18;

    private User(String username,int age) {
      System.out.println("有参构造" + username);
    }

    public User() {
        System.out.println("无参构造");
    }

    public void info(String username) {
        System.out.println("公共 -> info");
        System.out.println("姓名为:" + username);
    }

    private void show(String username) {
        System.out.println("私有 -> show");
        System.out.println("姓名为:" + username);
    }
}

测试类:

public class TestGetClass {
    public static void main(String[] args) throws ClassNotFoundException {
        // 1. 已知类名
        Class<User> c1 = User.class;

        // 2. 已知变量
        User user = new User();
        Class<? extends User> c2 = user.getClass();

        // 3. 已知包名
        Class<?> c3 = Class.forName("reflect.User");

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);

        // c1 c2 c3 相等
        System.out.println(c1 == c2); // true
        System.out.println(c2 == c3); // true
    on    System.out.println(c3 == c1); // true
    }
}

4. 获取构造器(Constructor )

在这里插入图片描述

1. 公共构造
代码实现:

package reflect;

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

public class TestPublicConstructor {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取Class
        Class clazz = User.class;

        // 2. 获取构造器  User()
        Constructor constructor = clazz.getConstructor();

        // 3. 通过构造器创建对象 new
        Object o = constructor.newInstance();

        System.out.println(o);
    }
}

2. 私有构造

package reflect;

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

public class TestPrivateConstructor {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取类名
        Class<?> clazz = Class.forName("reflect.User");

        // 2. 获取构造器 【获取声明的构造器】 User(String username)
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);

        // 3. 设置访问权限  因为声明的User(String username)构造器是私有的,私有不能访问,会报错,所以要设置访问权限
        declaredConstructor.setAccessible(true);

        // 4. 创建实例
        Object o = declaredConstructor.newInstance("rose");

        System.out.println(o);
    }
}

3. 反射获取构造器的作用
其实构造器的作用:初始化对象并返回

这里我们需要用到如下的两个方法,注意:这两个方法时属于Constructor的,需要用Constructor对象来调用。
在这里插入图片描述

5. 获取成员方法(Method)

在这里插入图片描述
Method提供的方法:
在这里插入图片描述

1. 公共成员方法

package reflect;

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

public class TestPublicMethod {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取类名
        Class clazz = Class.forName("reflect.User");

        // 2. 获取构造器  User()
        Constructor constructor = clazz.getConstructor();

        // 3. 通过构造器创建对象 new
        Object o = constructor.newInstance();

        // 4. 获取方法  info()
        Method method = clazz.getMethod("info", String.class);

        // 5. 执行方法 user.   ("jack")
        method.invoke(o, "jack");
    }
}

2. 私有成员方法

package reflect;

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

public class TestPrivateMethod {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 1. 获取class
        Class clazz = Class.forName("reflect.User");

        // 2. 获取构造器
        Constructor constructor = clazz.getConstructor();

        // 3. 通过构造器创建对象
        Object o = constructor.newInstance();

        // 4. 获取方法
        Method method = clazz.getDeclaredMethod("show", String.class);

        // 5. 设置访问权限
        method.setAccessible(true);

        // 6. 执行方法
        method.invoke(o,"rose");
    }
}

6. 获取成员变量(Field)

在这里插入图片描述
Field提供的方法:
在这里插入图片描述

1. 公共成员变量

package reflect;

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

public class TestPublicField {
    public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        // 1. 获取类名
        Class clazz = Class.forName("reflect.User");

        // 2. 获取构造器
        Constructor constructor =clazz.getConstructor();

        // 3. 通过构造器创建对象实例
        Object o = constructor.newInstance();

        // 4. 获取公共成员变量
        Field field = clazz.getField("age");

        // 5. 设置
        field.set(o,13);

        // 6. 获取
        System.out.println(field.getInt(o));  // 获取的类型是字符就用get()

    }
}

2. 私有成员变量

package reflect;

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

public class TestPrivateField {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        // 1. 获取类名
        Class clazz = Class.forName("reflect.User");

        // 2. 获取构造器
        Constructor constructor = clazz.getConstructor();

        // 3. 通过构造器创建对象实例
        Object o = constructor.newInstance();

        // 4. 获取私有成员变量
        Field username = clazz.getDeclaredField("username");

        // 5. 设置访问权限
        username.setAccessible(true);

        // 6. 设置内容
        username.set(o, "rose");

        // 7. 获取内容
        Object o1 = username.get(o);

        System.out.println(o1);
    }
}

总之,Java反射机制是一种强大的工具,它允许我们在运行时动态地访问、修改和应用对象的状态和行为。然而,需要注意的是,反射机制的使用应当谨慎,避免过度使用导致代码效率下降和性能问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值