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();