java:非静态内部类中的Filed:this$0

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。java:非静态内部类中的Filed:this$0,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!