创建一个父类UpperKk
public class UpperKk {
public short upperS;
public byte upperB;
}
创建一个子类Kk,继承UpperKk
public class Kk extends UpperKk{
private int i;
private boolean flag;
public long l;
}
单独创建一个测试类,测试getDeclaredFields()
public class T {
public static void main(String[] args) throws Exception{
Class clz = Class.forName("Kk");
Kk k = (Kk) clz.getDeclaredConstructor().newInstance();
Field[] fields = k.getClass().getDeclaredFields();
for(Field f:fields){
System.out.println("属性名称:"+f.getName());
System.out.println("属性类型:"+f.getType().getName());
System.out.println("---------------------------");
}
}
}
运行结果,可以取到子类所有属性的名称和类型
属性名称:i
属性类型:int
---------------------------
属性名称:flag
属性类型:boolean
---------------------------
属性名称:l
属性类型:long
---------------------------
如果要取属性的值,可不可以呢?
public class T {
public static void main(String[] args) throws Exception{
Class clz = Class.forName("Kk");
//在jdk9之后clz.newInstance()被废弃,所以使用下列方法创建实例
Kk k = (Kk) clz.getDeclaredConstructor();
Field[] fields = k.getClass().getDeclaredFields();
for(Field f:fields){
//f.setAccessible(true);
System.out.println("属性名称:"+f.getName());
System.out.println("属性类型:"+f.getType().getName());
System.out.println("属性值:"+f.get(k));
System.out.println("---------------------------");
}
}
}
运行报错,提示说取不到属性为private的值
属性名称:i
属性类型:int
Exception in thread "main" java.lang.IllegalAccessException: class Ttt cannot access a member of class Kk with modifiers "private"
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:361)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:591)
at java.base/java.lang.reflect.Field.checkAccess(Field.java:1075)
at java.base/java.lang.reflect.Field.get(Field.java:416)
at Ttt.main(Ttt.java:15)
将f.setAccessible(true)
取消注释,运行成功,子类中的所有属性的值都取到了
属性名称:i
属性类型:int
属性值:0
---------------------------
属性名称:flag
属性类型:boolean
属性值:false
---------------------------
属性名称:l
属性类型:long
属性值:0
---------------------------
测试getFields()
public class T {
public static void main(String[] args) throws Exception{
Class clz = Class.forName("Kk");
//在jdk9之后clz.newInstance()被废弃,所以使用下列方法创建实例
Kk k = (Kk) clz.getDeclaredConstructor();
Field[] fields = k.getClass().getFields();
for(Field f:fields){
System.out.println("属性名称:"+f.getName());
System.out.println("属性类型:"+f.getType().getName());
System.out.println("属性值:"+f.get(k));
System.out.println("---------------------------");
}
}
}
运行成功,取到了子类和父类中的public的属性
属性名称:l
属性类型:long
属性值:0
---------------------------
属性名称:upperS
属性类型:short
属性值:0
---------------------------
属性名称:upperB
属性类型:byte
属性值:0
---------------------------
总结
getFields()
可以取到子类和父类中的public的属性
getDeclaredFields()
取不到父类中的属性,可以取到子类中的所有属性的类型和名称,但是默认情况下取不到private的属性的值,需要修改setAccessible(true)
才可以