java:非静态内部类中的Filed:this$0
1 前言
通过反射方法getDeclaredFields()获取类Class的全部字段时,会发现内部类(非静态)的字段中,存在父类的实例字段,修饰为final,属性名为this$0。若此非静态内部类需要调用父类的实例方法,那么使用parent class.this即可。
2 使用
public class TestFields {
public static void main(String[] args) {
new TestFields().new Fruit().run();
System.out.println(Arrays.toString(getAllDeclaredFieldList(Fruit.class)));
System.out.println(Arrays.toString(Fruit2.class.getDeclaredFields()));
System.out.println(Arrays.toString(Fruit3.class.getDeclaredFields()));
}
private void run(){
System.out.println("TestFields run");
}
@ToString
@Data
private class Fruit{
String fruitName;
// 使用 parent class.this可调用父类实例方法
public void run(){
TestFields.this.run();
}
}
@ToString
@Data
private static class Fruit2{
String fruitName;
}
public static Field[] getAllDeclaredFieldList(Class<?> clazz){
Field[] allFieldList = null;
do{
Field[] declaredFields = clazz.getDeclaredFields();
allFieldList = ArrayUtils.addAll(allFieldList, declaredFields);
clazz = clazz.getSuperclass();
}while(clazz != null && !clazz.equals(Object.class));
return allFieldList;
}
}
@ToString
@Data
class Fruit3{
String fruitName;
}
执行结果如下:
TestFields run
[java.lang.String xiaoxu.project.TestFields$Fruit.fruitName,
final xiaoxu.project.TestFields xiaoxu.project.TestFields$Fruit.this$0]
[java.lang.String xiaoxu.project.TestFields$Fruit2.fruitName]
[java.lang.String xiaoxu.project.Fruit3.fruitName]
会发现非静态的内部类Fruit中,全部字段除了fruitName外,还具有final 修饰的this$0变量,该变量为父类TestFields实例对象,而静态内部类Fruit2中则没有该变量。
可以反射获取this$0变量对象,一般不需如此操作。若非静态内部类Fruit中需要使用父类TestFields的实例方法,如下使用TestFields.this亦可:
@ToString
@Data
private class Fruit{
String fruitName;
// 使用 parent class.this可调用父类实例方法
public void run(){
TestFields.this.run();
}
}
最后,若希望getAllDeclaredFieldList方法不会获取到非静态内部类中的this$0字段,简单增加如下过滤即可:
public static Field[] getAllDeclaredFieldList(Class<?> clazz){
Field[] allFieldList = null;
do{
Field[] declaredFields = clazz.getDeclaredFields();
Field[] fields = Arrays.stream(declaredFields)
.filter(field -> !("this$0".equals(field.getName())
&& Modifier.isFinal(field.getModifiers())))
.toArray(new IntFunction<Field[]>() {
@Override
public Field[] apply(int value) {
return new Field[value];
}
});
allFieldList = ArrayUtils.addAll(allFieldList, fields);
clazz = clazz.getSuperclass();
}while(clazz != null && !clazz.equals(Object.class));
return allFieldList;
}
过滤了非静态内部类中的this$0父类实例Field,再次执行结果如下:
TestFields run
[java.lang.String xiaoxu.project.TestFields$Fruit.fruitName]
[java.lang.String xiaoxu.project.TestFields$Fruit2.fruitName]
[java.lang.String xiaoxu.project.Fruit3.fruitName]
另外非静态内部类中不含有无参构造方法,建议需要反射调用newInstance()方法时,使用public定义的实体类。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192079.html