前面介绍了获取Class实例的三个方法,现在来介绍根据Class实例访问其属性
新建一个springboot项目,名称为reflection,该项目继承了一个父项目springboot-parent,后续的有关文章都是在这个项目上进行开发,父项目只是定义了依赖,我就不粘贴出来了,不懂的可以去看看maven的拆分聚合
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.fandy</groupId>
<artifactId>springboot-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<artifactId>reflection</artifactId>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
新建一个field包,访问属性的操作都在这个包里进行,在field包下新建一个User类和SubUser类,SubUser继承User
User.class
@Data
public class User {
public String name;
private Integer age;
}
User类定义了两个属性,一个是公有的name,一个是私有的age
SubUser.class
@Data
public class SubUser extends User{
public String sex;
private String address;
}
SubUser类定义了两个属性,一个是公有的sex,一个是私有的address
测试
Logger logger = LoggerFactory.getLogger(ReflectionApplicationTests.class);
@Test
void testFields() {
try {
Class cls = Class.forName("com.fandy.reflection.field.SubUser");
Field field1 = cls.getField("name"); //根据字段名获取类型为public的字段(包括父类)
Field[] field2 = cls.getFields(); //获取所有的类型为public的字段(包括父类)
Field field3 = cls.getDeclaredField("address"); //根据字段名获取本类的字段
Field[] field4 = cls.getDeclaredFields(); //获取本类所有的字段
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (NoSuchFieldException e1){
e1.printStackTrace();
}
}
由上述代码可以看出,根据Class实例访问其属性有四个方法,分别是
- getField(name)
- getFields()
- getDeclaredField(name)
- getDeclaredFields()
前两个方法只能访问公有类型的属性,也包括父类,后两个方法能访问全部类型的属性,但只能是本类
接下来看看Field对象的操作
Logger logger = LoggerFactory.getLogger(ReflectionApplicationTests.class);
@Test
void testFields() {
try {
Class cls = Class.forName("com.fandy.reflection.field.SubUser");
Field field1 = cls.getField("name"); //根据字段名获取类型为public的字段(包括父类)
Field[] field2 = cls.getFields(); //获取所有的类型为public的字段(包括父类)
Field field3 = cls.getDeclaredField("address"); //根据字段名获取本类的字段
Field[] field4 = cls.getDeclaredFields(); //获取本类所有的字段
logger.info("属性名:"+field1.getName());
logger.info("属性类型:"+field1.getType());
logger.info("属性的修饰符:"+field1.getModifiers());
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (NoSuchFieldException e1){
e1.printStackTrace();
}
}
控制台日志输出
常用的操作就是这三个,当然还有别的操作,这里就不进行演示了,其中getModifiers返回的是int,不同的值表示不同的修饰符
现在来看看设置属性值并获取属性值
Logger logger = LoggerFactory.getLogger(ReflectionApplicationTests.class);
@Test
void testFields() {
try {
SubUser user = new SubUser();
Class cls = user.getClass();
Field field = cls.getField("sex");
field.setAccessible(true);
field.set(user,"张三");
Object value = field.get(user);
System.out.println(value);
}catch (NoSuchFieldException e1){
e1.printStackTrace();
}catch (IllegalAccessException e2){
e2.printStackTrace();
}
}
控制台输出
可看到,通过反射设置属性值的方法是set(object,value),获取属性值的方法是get(object)
关于反射操作属性的介绍就到这里啦~~~~~