Java 在构造时传递子实例

Java 在构造时传递子实例,java,generics,Java,Generics,我有一个父类,其方法需要利用子类实例,但我似乎无法通过构造函数传递它: public abstract class CodelanxPlugin<E extends CodelanxPlugin<E>> /* other inheritance */ { private final E plugin; public CodelanxPlugin(E plugin) { this.plugin = plugin; } @

我有一个父类,其方法需要利用子类实例,但我似乎无法通过构造函数传递它:

public abstract class CodelanxPlugin<E extends CodelanxPlugin<E>> /* other inheritance */ {

    private final E plugin;

    public CodelanxPlugin(E plugin) {
        this.plugin = plugin;
    }

    @Override
    public void onEnable() {
        //need to be able to use the plugin instance
    }

}
这当然是不可能的,因为您不能
super(this)
。如何在构造时传递子实例

我的一个想法是:

public MyPlugin() {
    super(new Box<MyPlugin>(this).getInst());
}

private class Box<E> {

    private E inst;

    public Box(E inst) {
        this.inst = inst;
    }

    public E getInst() {
        return this.inst;
    }
}
如果我将
传递给
ListenerManager
构造函数,我将收到以下编译器错误:

错误:不兼容的类型:无法推断ListenerManager的类型参数

如果我使用新ListenerManager(此),那么我的错误是:

错误:不兼容的类型:无法将CodelanxPlugin转换为E


您根本不需要将“this”传递给您父母的构造函数MyPlugin的构造函数中的“this”与CodelanxPlugin的构造函数中的“this”指的是同一个对象

所以你写的只是:

 public CodelanxPlugin() {
    this.plugin = (E) this;
}

然后,您应该想知道wy您无论如何都需要一个“plugin”字段,因为“this”总是可用的。。。从您的解释中,我觉得您正在寻找新的方法。

我认为您可能对子类化的工作原理感到困惑。(要么是这样,要么就是我完全搞不清楚你想完成什么。)如果你有一个类
C
和一个子类
Sub

class C {
}

class Sub extends C {
}
当程序说
new Sub()
时,它会创建一个新实例。此对象是
Sub
的实例,也是
C
的实例。谈论
C
引用“子实例”的方法是没有意义的

如果您有
子对象

Sub myObject = new Sub();
然后调用在
C
中运行代码的方法:

class C {
    public void someMethod() {
        // someMethod logic
    }
}

myObject.someMethod();
假设这个方法没有被覆盖。现在您进入了标记为
somemethodlogic
的部分。在该部分中,
this
引用了您调用它的对象实例(
myObject
)——它既是
C
的实例,也是
Sub
的实例。您不需要单独的语法来引用“子实例”,因为没有这样的单独的东西

因此,在您最初的示例中,如果您希望
plugin
字段成为“您刚刚创建的同一对象的子实例”,请将其删除。你不需要它


另一方面,如果你正在创建一个新对象,并给这个新对象一个不同的,以前创建的对象的引用,那就完全是另一回事了。但是我不是这样理解你的问题的。

主要问题是
这个
并不等同于插件实例本身,因为我有我要传递给
E
的子类。我会更新我的问题很抱歉坚持,但是在您的更新代码中,为什么您不能简单地编写
this.listener=newlistenermanager((E)this)?哈!铸造我不知道为什么我没有想到这一点。不,泛型确实是一个常见的困惑来源。它们可能会有很大帮助,但正确的使用需要透彻的理解,不幸的是,手动强制转换技巧经常是必要的,特别是当将类作为参数传递给父类时。这种强制转换是不安全的
E
CodelanxPlugin
的子类型,但
CodelanxPlugin
(此
的类型)不是
E
的子类型。(如果它是安全的,那么一开始就不需要强制转换。)是的,直到泛型,比如说,
Sub扩展了C
!=<父类中的code>C
,这似乎是我的编译器问题。没有充分的理由使用
class CodelanxPlugin
而不是
class CodelanxPlugin
Sub myObject = new Sub();
class C {
    public void someMethod() {
        // someMethod logic
    }
}

myObject.someMethod();