Java 反射(Reflection)

在本教程中,我们将学习反射,这是Java编程中的一个特性,它允许我们检查和修改类、方法等。

在Java中,反射允许我们在运行时检查和操作类、接口、构造函数、方法和字段。

Java 类名为Class

在学习Java反射之前,我们需要了解一个名为Class的Java类。

Java中有一个名为Class的类,该类在运行时保留有关对象和类的所有信息。

Class对象描述了特定类的属性。该对象用于执行反射。

创建名为Class的类的对象

我们可以创建Class的对象,通过:

  • 使用forName()方法

forName()接受字符串参数(类的名称)并返回Class对象。返回的对象引用字符串指定的类。例如,

ClassDog{}Classc1=Class.forName("Dog");
  • 使用getClass()方法

getClass()方法使用特定类的对象来创建新的对象Class。例如,

Dogd1=newDog()Classc1=d1.getClass();
  • 使用.class

我们还可以使用.class扩展名创建Class对象。例如,

Classc1=Dog.class;

创建Class对象后,我们可以使用这些对象执行反射。

获取接口

我们可以使用Class的getInterfaces()方法来收集类实现的接口的信息。此方法返回一个接口数组。

示例:获取接口

importjava.lang.Class;importjava.lang.reflect.*;interfaceAnimal{publicvoiddisplay();}interfaceMammal{publicvoidmakeSound();}classDogimplementsAnimal,Mammal{publicvoiddisplay(){System.out.println("Iamadog.");}publicvoidmakeSound(){System.out.println("Barkbark");}}classReflectionDemo{publicstaticvoidmain(String[]args){try{//创建一个Dog类的对象Dogd1=newDog();//使用getClass()创建Class对象Classobj=d1.getClass();//查找由Dog实现的接口Class[]objInterface=obj.getInterfaces();for(Classc:objInterface){//打印接口名称System.out.println("InterfaceName:"+c.getName());}}catch(Exceptione){e.printStackTrace();}}}

输出结果

InterfaceName:AnimalInterfaceName:Mammal

获取超类和访问修饰符

类Class的方法getSuperclass()可用于获取有关特定类的超类的信息。

而且,Class提供了一种getModifier()方法,该方法以整数形式返回class的修饰符。

示例:获取超类和访问修饰符

importjava.lang.Class;importjava.lang.reflect.*;interfaceAnimal{publicvoiddisplay();}publicclassDogimplementsAnimal{publicvoiddisplay(){System.out.println("Iamadog.");}}classReflectionDemo{publicstaticvoidmain(String[]args){try{//创建一个Dog类的对象Dogd1=newDog();//使用getClass()创建Class对象Classobj=d1.getClass();//以整数形式获取Dog的访问修饰符intmodifier=obj.getModifiers();System.out.println("修饰符:"+Modifier.toString(modifier));//找到Dog的超类ClasssuperClass=obj.getSuperclass();System.out.println("Superclass:"+superClass.getName());}catch(Exceptione){e.printStackTrace();}}}

输出结果

修饰符:publicSuperclass:Animal

反射字段,方法和构造函数

该软件包java.lang.reflect提供了可用于操作类成员的类。例如,

  • 方法类 - 提供有关类中方法的信息

  • 字段类 - 提供有关类中字段的信息

  • 构造函数类 - 提供有关类中构造函数的信息

Java 反射与字段

我们可以使用Field类提供的各种方法检查和修改类的不同字段。

  • getFields() - 返回该类及其超类的所有公共字段

  • getDeclaredFields() - 返回类的所有字段

  • getModifier() - 以整数形式返回字段的修饰符

  • set(classObject,value) - 使用指定的值设置字段的值

  • get(classObject) - 获取字段的值

  • setAccessible(boolean) - 使私有字段可访问

注意:如果我们知道字段名称,则可以使用

  • getField("fieldName") - 从类返回名称为fieldName的公共字段。

  • getDeclaredField("fieldName") - 从类返回名称为fieldName的字段。

示例:访问访问公共字段

importjava.lang.Class;importjava.lang.reflect.*;classDog{publicStringtype;}classReflectionDemo{publicstaticvoidmain(String[]args){try{Dogd1=newDog();//创建Class对象Classobj=d1.getClass();//操纵Dog类的公共字段typeFieldfield1=obj.getField("type");//设置字段的值field1.set(d1,"labrador");//通过转换成字符串来获取字段的值StringtypeValue=(String)field1.get(d1);System.out.println("type:"+typeValue);//获取类型的访问修饰符intmod1=field1.getModifiers();Stringmodifier1=Modifier.toString(mod1);System.out.println("修饰符:"+modifier1);System.out.println("");}catch(Exceptione){e.printStackTrace();}}}

输出结果

type:labrador修饰符:public

示例:访问私有字段

importjava.lang.Class;importjava.lang.reflect.*;classDog{privateStringcolor;}classReflectionDemo{publicstaticvoidmain(String[]args){try{Dogd1=newDog();//创建类Class对象Classobj=d1.getClass();//访问私有字段Fieldfield2=obj.getDeclaredField("color");//使私有字段可访问field2.setAccessible(true);//设置color值field2.set(d1,"brown");//getthevalueoftypeconvertinginStringStringcolorValue=(String)field2.get(d1);System.out.println("color:"+colorValue);//获取color的访问修饰符intmod2=field2.getModifiers();Stringmodifier2=Modifier.toString(mod2);System.out.println("modifier:"+modifier2);}catch(Exceptione){e.printStackTrace();}}}

输出结果

color:brownmodifier:private

Java 反射与方法

像字段一样,我们可以使用Method类提供的各种方法来检查类的不同方法。

  • getMethods() - 返回该类及其超类的所有公共方法

  • getDeclaredMethod() - 返回该类的所有方法

  • getName() - 返回方法的名称

  • getModifiers() - 以整数形式返回方法的访问修饰符

  • getReturnType() - 返回方法的返回类型

示例:方法反射

importjava.lang.Class;importjava.lang.reflect.*;classDog{publicvoiddisplay(){System.out.println("Iamadog.");}protectedvoideat(){System.out.println("Ieatdogfood.");}privatevoidmakeSound(){System.out.println("BarkBark");}}classReflectionDemo{publicstaticvoidmain(String[]args){try{Dogd1=newDog();//创建一个Class对象Classobj=d1.getClass();//使用getDeclaredMethod()获取所有方法Method[]methods=obj.getDeclaredMethods();//获取方法的名称for(Methodm:methods){System.out.println("方法名称:"+m.getName());//获取方法的访问修饰符intmodifier=m.getModifiers();System.out.println("修饰符:"+Modifier.toString(modifier));//获取方法的返回类型System.out.println("ReturnTypes:"+m.getReturnType());System.out.println("");}}catch(Exceptione){e.printStackTrace();}}}

输出结果

方法名称:display修饰符:publicReturntype:void方法名称:eat修饰符:protected返回类型:void方法名称:makeSound修饰符:private返回类型:void

Java 反射与构造函数

我们还可以使用Constructor类提供的各种方法检查类的不同构造函数。

  • getConstructors() - 返回该类的所有公共构造函数以及该类的超类

  • getDeclaredConstructor() -返回所有构造函数

  • getName() - 返回构造函数的名称

  • getModifiers() - 以整数形式返回构造函数的访问修饰符

  • getParameterCount() - 返回构造函数的参数数量

示例:构造函数反射

importjava.lang.Class;importjava.lang.reflect.*;classDog{publicDog(){}publicDog(intage){}privateDog(Stringsound,Stringtype){}}classReflectionDemo{publicstaticvoidmain(String[]args){try{Dogd1=newDog();Classobj=d1.getClass();//使用getDeclaredConstructor()获取一个类中的所有构造函数Constructor[]constructors=obj.getDeclaredConstructors();for(Constructorc:constructors){//获取构造函数的名称System.out.println("构造函数名称:"+c.getName());//获取构造函数的访问修饰符intmodifier=c.getModifiers();System.out.println("修饰符:"+Modifier.toString(modifier));//获取构造函数中的参数数量System.out.println("参数个数:"+c.getParameterCount());}}catch(Exceptione){e.printStackTrace();}}}

输出结果

构造函数名称:Dog修饰符:public参数个数:0构造函数名称:Dog修饰符:public参数个数:1构造函数名称:Dog修饰符:private参数个数:2
编辑于2024-05-20 12:12