有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何从子类实例获取定义类实例?

如果我有此代码:

public class MySuperClass {
    public String superString = "hello";

    public MyChildClass makeChild() {
        return new MyChildClass();
    }

    public class MyChildClass {
        public String childString = "hi";
    }
}

如何从MyChildClass实例获取MySuperClass实例? 因为我有这个错误: enter image description here

关于stackoverflow也有很多类似的问题,但这不是其中任何一个的重复。 我的代码中有什么错误?如果不在嵌套类中创建返回MySuperClass的方法,我如何实现上面所说的呢。这假设我没有MySuperClass的代码

我认为这是可以做到的,因为在MyChildClass中,我可以通过MySuperClass.this访问超级实例,如何从子类外部将MySuperClass实例附加到子类

编辑:我知道铸造不是实现这一点的方法,它是一种尝试,以实现我想要的


共 (1) 个答案

  1. # 1 楼答案

    你在混用术语。“子类”通常用于这种关系:

    public class Parent {}
    public class Child extends Parent {}
    

    (这里的“家长”被称为孩子的“超类”)

    在这种情况下,“我怎样才能从我的子类中得到我的超类”毫无意义。Child是Parent的一个扩展,当你写new Child()时,只有一个实例,这个实例是Child和Parent中内容的组合。这不是两件独立的事情

    你说的是内部的类。这种关系:

    public class Outer {
        public class Inner {}
    }
    

    内部/外部,与子/父或子/超级

    所以,你实际上要问的是:如何获得外部类实例

    这是不可能的。这是Inner的一个实现细节,由Inner来公开这一点。如果它不想,你就无法访问它

    但也有黑客和变通方法

    选项#1:Inner中的代码本身就可以做到这一点

    在与class Inner {}相关的{}中,您可以执行以下操作:

    class Outer {
        class Inner {
            public Outer getOuterInstance() {
                return Outer.this;
            }
        }
    }
    

    选项2:破解它

    在类/JVM级别,内部/外部类不存在。它们都只是课程。这就是为什么,如果编译上述内容,最终会得到两个类文件,而不是一个:Outer.classOuter$Inner.class。内部的外部实例由一个字段表示

    这个字段通常被称为this$0,是包私有的。比如:

    Field f = Inner.class.getDeclaredField("this$0");
    f.setAccessible(true);
    Outer outer = (Outer) f.get(instanceOfInner);
    

    但是,如果反射代码还没有为您阐明这一点:不要。这是一个可怕的想法。安全管理员可以阻止你。代码很难读懂,除非你用解释你在做什么的注释来解释,否则毫无意义。最重要的是,就像任何反思一样,这完全不是《外部/内部》的作者想要你做的事情,无论你使用外部的什么,在未来的某个小版本中可能根本无法“正常工作”,因为你没有以预期的方式使用这个库,因此任何为它提供的支持都会丢失。你自己铺路,这很糟糕,因为你不知道作者真正的意图是什么,你现在不得不说,你的库在没有广泛测试的情况下永远不能更新,不更新是让你自己被黑客攻击的一个很好的公式。这在很多方面都是个坏主意

    还有,正如当前OpenJDK团队所表达的,对向后兼容性的关注显著减少(参见jigsaw项目,这是很长一段时间以来最具突破性的java版本,OpenJDK团队几乎决定在一个版本的跳转中摆脱SecurityManager,直到被社区召回,积极扩展几乎毫无意义的“开放”检查,等等)——这意味着如果你依赖它,如果java18或其他东西永久性地破坏了你的能力,不要感到惊讶

    所以,不要这样做

    警告:非静态内部类很糟糕

    认为内部类实际上有一个外部类型的不可见字段的想法既恼人又令人惊讶。它会停止垃圾收集。这让普通的java程序员感到困惑,因为按照预期的方式“使用”这个java功能是非常罕见的

    因此,我强烈建议您始终将内部类static,如果您真的想要Outer的实例,请将其显式化:使Inner静态,然后给它一个private final Outer outer;字段

    它同样高效,打字稍微多一点,但可读性要高得多