【Java 基础】Java 反射使用方法简介

【Java 基础】Java 反射使用方法简介



一、反射简介

Java 反射机制是一个很强大的机制,它可以让使用者能在运行的时候进行类的操作

1. 获取 Class 的方法

  1. getClass() 方法
Class testClazz = Test.getClass()
  1. 类名.class
Class testClazz = Test.class
  1. Class.forName() 方法
Class testClazz = Class.forName("com.test.Test")

2. Class 类常用方法解释

方法返回类型所属类解释
getFields()Field[]java.lang.Class获取类中所有 public 修饰的变量
getDeclaredFields()Field[]java.lang.Class获取类中所有的变量
getField(String)Fieldjava.lang.Class获取指定名称的变量
getMethods()Method[]java.lang.Class获取类中所有 public 修饰的方法
getDeclaredMethods()Method[]java.lang.Class获取类中所有的方法
getMethod(String, Class…)Methodjava.lang.Class获取指定名称的方法, 可以填写参数类型
getConstructors()Constructor[]java.lang.Class获取类中所有 public 修饰的构造器
getDeclaredConstructors()Constructor[]java.lang.Class获取类中所有的构造器
getConstructor(Class…)Constructorjava.lang.Class获取指定参数类型的构造器, 参数需要填写参数类型, 如果有多个参数, 则可以填写多个参数类型
getAnnotations()Annotation[]java.lang.Class获取所有 public 修饰的注解
getDeclaredAnnotations()Annotation[]java.lang.Class获取所有的注解
getAnnotation(Class)Annotationjava.lang.Class获取指定类型的注解, 参数中需要填写注解类型
getModifiers()intjava.lang.Class获取所有的修饰符类型, 会返回 int 类型的值, 可以使用 Modifier.toString() 进行值的解析
getSuperclass()Classjava.lang.Class获取父类, 如果没有继承父类, 则会返回 null
getInterfaces()Class[]java.lang.Class获取所有的接口
newInstance()Tjava.lang.Class生成类的实例

3. 例子

【1】获取类中所有构造器、方法、变量

在例子中,分别打印了构造器、方法、变量,从打印出来的结果来看,带 Declared 的方法会只会获取当前类所有修饰类型的方法或者变量,而不带 Declared 的方法则会获取类所有 public 的方法或者变量,包括继承的父类以及实现的接口中的 public 修饰的方法或者变量也会打印出来。

一句话总结就是:如果要找当前类以及父类和接口中的 public 的内容,则使用不带 Declared 的方法,如果要查找当前类中所有修饰符修饰的内容,则使用带 Declared 的方法。

  • AbstractTest.java
public abstract class AbstractTest {  
  
    private String abstractField;  
  
    public Double abstractDoubleField;  
  
    public AbstractTest() {  
  
    }  
  
    abstract void abstractMethod();  
  
    private void abstractPrivateMethod() {  
        System.out.println("abstractPrivateMethod");  
    }  
  
    public void abstractPublicMethod() {  
        System.out.println("abstractPublicMethod");  
    }  
}
  • TestInterface.java
public interface TestInterface {  
  
    String interfaceField = "接口变量";  
  
    default void interfaceDefaultMethod() {  
        System.out.println("interfaceMethod");  
    }  
  
    String interfacePublicMethod();  
}
  • Test.java
class Test extends AbstractTest implements TestInterface {  
  
    private String testName;  
  
    protected Double size;  
  
    public String testClass;  
  
    private Test() {  
  
    }  
  
    public Test(String testName, Double size) {  
        this.testName = testName;  
        this.size = size;  
    }  
  
    public String getTestName() {  
        return testName;  
    }  
  
    public void setTestName(String testName) {  
        this.testName = testName;  
    }  
  
    private void testMethod() {  
        System.out.println("测试方法");  
    }  
  
    public static String testPrint() {  
        System.out.println("打印测试方法");  
        return "测试";  
    }  
  
    @Override  
    void abstractMethod() {  
        System.out.println("abstractMethod");  
    }  
  
    @Override  
    public String interfacePublicMethod() {  
        System.out.println("interfacePublicMethod");  
        return "interfacePublicMethod";  
    }  
}
  • ReflectionTest.java
public class ReflectionTest {  
  
    public static void main(String[] args) {  
        ReflectionTest test = new ReflectionTest();  
  
        System.out.println("Constructors:");  
        test.printConstructors(Test.class);  
        System.out.println("======================================");  
        System.out.println("DeclaredConstructors:");  
        test.printDeclaredConstructors(Test.class);  
        System.out.println("======================================");  
        System.out.println("Fields:");  
        test.printFields(Test.class);  
        System.out.println("======================================");  
        System.out.println("DeclaredFields:");  
        test.printDeclaredFields(Test.class);  
        System.out.println("======================================");  
        System.out.println("Methods:");  
        test.printMethods(Test.class);  
        System.out.println("======================================");  
        System.out.println("DeclaredMethods:");  
        test.printDeclaredMethods(Test.class);  
    }  
  
    public void printConstructors(Class<Test> clazz) {  
        Constructor<?>[] constructors = clazz.getConstructors();  
  
        this.constructorsPrint(constructors);  
    }  
  
    public void printDeclaredConstructors(Class<Test> clazz) {  
        Constructor<?>[] constructors = clazz.getDeclaredConstructors();  
  
        this.constructorsPrint(constructors);  
    }  
  
    private void constructorsPrint(Constructor<?>[] constructors) {  
        for (Constructor<?> constructor : constructors) {  
            String constructorName = constructor.getName();  
            System.out.println("构造器名:" + constructorName + " {");  
  
            String modifiers = Modifier.toString(constructor.getModifiers());  
            System.out.print("修饰符:");  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + ";");  
            }  
  
            Class<?>[] parameterTypes = constructor.getParameterTypes();  
            System.out.print("\n" + "参数类型:");  
            for (Class<?> parameterType : parameterTypes) {  
                System.out.print(parameterType.getName() + "; ");  
            }  
  
            System.out.println("\n" + "}");  
        }  
    }  
  
    public void printFields(Class<Test> clazz) {  
        Field[] fields = clazz.getFields();  
  
        this.fieldPrint(fields);  
    }  
  
    public void printDeclaredFields(Class<Test> clazz) {  
        Field[] declaredFields = clazz.getDeclaredFields();  
  
        this.fieldPrint(declaredFields);  
    }  
  
    private void fieldPrint(Field[] fields) {  
        for (Field field : fields) {  
            String fieldName = field.getName();  
            Class<?> fieldType = field.getType();  
  
            System.out.println("变量名:" + fieldName + " {");  
            System.out.println("变量类型:" + fieldType);  
  
            String modifiers = Modifier.toString(field.getModifiers());  
            System.out.print("修饰符:");  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + ";");  
            }  
  
            System.out.println("\n" + "}");  
        }  
    }  
  
    public void printMethods(Class<Test> clazz) {  
        Method[] methods = clazz.getMethods();  
  
        this.methodPrint(methods);  
    }  
  
    public void printDeclaredMethods(Class<Test> clazz) {  
        Method[] declaredMethods = clazz.getDeclaredMethods();  
  
        this.methodPrint(declaredMethods);  
    }  
  
    private void methodPrint(Method[] methods) {  
        for (Method method : methods) {  
            String methodName = method.getName();  
            Class<?> returnType = method.getReturnType();  
  
            System.out.println("方法名:" + methodName + " {");  
            System.out.println("返回类型:" + returnType);  
  
            String modifiers = Modifier.toString(method.getModifiers());  
            System.out.print("修饰符:");  
            if (modifiers.length() > 0) {  
                System.out.print(modifiers + ";");  
            }  
  
            System.out.println("\n" + "}");  
        }  
    }  
}

【2】访问并设置 private 修饰的变量值

如果想要对当前类中某个使用 private 修饰的变量进行访问并设置值,会出现下面的错误,来提示无法获取 private 修饰的变量的值:
java.lang.IllegalAccessException: Class test.common.ReflectionTest can not access a member of class test.common.Test with modifiers "private"

如果想获取 private 修饰的变量的值,则需要将 Java 的安全访问控制设置为可访问,才能对私有域进行访问。

Class<? extends Test> clazz = test.getClass();  
Field testName = clazz.getDeclaredField("testName");  
testName.setAccessible(true);  
Object testValue = testName.get(test);  
System.out.println(testName + " 旧值:" + testValue);  
  
testName.set(test, "新的 testName测试");  
Object newTestValue = testName.get(test);  
System.out.println(testName + " 新值:" + newTestValue);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞎叨叨的一天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值