【问题标题】:How do I recover reference to this$0 in a nested class?如何在嵌套类中恢复对 this$0 的引用?
【发布时间】:2015-11-20 11:11:55
【问题描述】:

我想知道是否有办法“手动”恢复this$0 的引用,换句话说,恢复到嵌套类中的外部类?

这意味着使用名称或methodOuterClass()OuterClass.this.Method() 引用外部类的任何方法或属性会导致NullPointerException

由于下面列出的问题,例如Gson,在不引用外部类的情况下构造对象。创建对象后是否可以修复此问题?

参考文献

GSON does not deserialize reference to outer class

using member of outer class in a inner class makes null exception?

【问题讨论】:

  • 您是否尝试过使用反射?即Field field = Outer.Inner.class.getDeclaredField("this$0"); field.setAccessible(true); field.set(inner, outer);
  • @BeyelerStudios 它有效,如果你想要功劳,请将其作为答案!

标签: java reflection


【解决方案1】:

感谢@BeyelerStudios,不幸的是,他没有将他的评论作为答案。

我正在用示例代码回答:

public class Outer {     
    protected Inner inner = null; 
    public Inner getInner() {
        return inner;
    }      
    protected void something(){ }
    public void function(){
       inner.fixParent(this); // solve the reference lost
       inner.innerFunction(this);
    }
    public static void main(String[] args){
        String str = "{\"inner\":{\"name\"=\"test\"}}";
        Outer outer = (new Gson()).fromJson(str,Outer.class);
        System.out.println(outer.getInner().name);
        outer.function();
    }

    public class Inner {
        public String name = null;

        private void fixParent(Outer parent){// solution here
            try {
                field = Inner.class.getDeclaredField("this$0");
                field.setAccessible(true);
                field.set(this, parent);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
       }
        protected void innerFunction(){
            Field field = null;                       
            something();//now works 
        }
    }
}

【讨论】:

    【解决方案2】:

    我遇到的一个现象:

    • 可序列化的内部类 - 外部类不是

    反序列化并再次序列化内部类对象之后,

    • OuterClass.thisnull

    内部类应该是静态的。或者非常昂贵,外部类使 Serializable。

    显然您需要OuterClass。如果您获得了序列化文件,您也许可以创建一个具有相同 serialVersionUID 的修补内部类,并将其转换为其他名称下该类的正确变体。

    那将是一些成就。将这样一个错误的实例转移到一个新的类对象可能会更容易。

    【讨论】:

    • @AdamSkywalker 现在是旧版软件,NPE 为 Outer.this 很久以前。我非常怀疑;事实上,现在我不能再说类定义是否发生了任何变化——在序列化和反序列化之间。 “可以试一试”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2019-11-13
    • 2022-01-05
    相关资源
    最近更新 更多