Java 确保子类是超类的泛型类型的实例

Java 确保子类是超类的泛型类型的实例,java,generics,inheritance,Java,Generics,Inheritance,我正在创建一个JavaUtils库,遇到了泛型的问题。我已经找到了一个让库工作的解决方案,但它看起来像是糟糕的代码实践,并且容易出现未被检测到的程序故障。出于问题的考虑,我已经将程序简化为一个最小可验证的示例 假设我有一个接口可调用,它被调用以实现E public interface Invokable<E> { void invoke(E e); } 如果您创建一个新的PrintingInvokableUser()并在其上调用开始(),它将创建一个新的Printing

我正在创建一个JavaUtils库,遇到了泛型的问题。我已经找到了一个让库工作的解决方案,但它看起来像是糟糕的代码实践,并且容易出现未被检测到的程序故障。出于问题的考虑,我已经将程序简化为一个最小可验证的示例

假设我有一个接口
可调用
,它被调用以实现
E

public interface Invokable<E> {

    void invoke(E e);

}
如果您创建一个
新的PrintingInvokableUser()
并在其上调用
开始()
,它将创建一个
新的PrintingInvokable()
并在其上调用
调用(this)
,然后将打印出
PrintingInvokableUser
方法

虽然我的代码确实可以做到这一点,但这取决于一个不成文的期望,即
InvokableUser
的子类
Foo
将扩展
InvokableUser
,涉及一个不检查的强制转换,这是错误的(并引发编译器警告),似乎甚至没有使用泛型类型,因为我可以用非泛型类型实现相同的效果,而且通常似乎必须有更好的方法来实现这一点


如果有人能为我指明正确的方向,我将不胜感激。谢谢

不可能避免在
(E)上得到警告。这是一个众所周知的问题。有一个(不满意的)解决方案叫做“getThis技巧”,你可以用谷歌搜索。我猜这是一个抽象的E方法,子类应该从中返回
this
?你猜对了。就我个人而言,我认为这是一个完全无用的解决方案,因为你必须在每一个类中重写它。是的,它似乎是编译器非强制要求和烦人的代码编写之间的选择。我想我必须在javadocs中非常明确地说明这个需求:p@Phoenix:“我猜这是一个抽象的E方法,子类应该从中返回这个”不需要返回
这个
。它返回一个类型为
E
(甚至可能与当前类的类型不同)的值。您可以在
E
与类的类型相同的情况下实现类,并且可以返回
this
。处于相同情况的其他人可以返回该类的其他实例。或者其他人可以拥有与类不同的
E
,然后他们将返回该类型的实例。不管怎样,它是类型安全的。
public interface InvokableFactory<E> {

    Invokable<E> create();

}
public class InvokableUser<E> {

    private InvokableFactory<E> factory;

    public InvokableUser(InvokableFactory<E> factory) {
        this.factory = factory;
    }

    public void start() {
        factory.create().invoke((E) this);
    }

}
public class PrintingInvokable implements Invokable<PrintingInvokableUser> {

    @Override
    public void invoke(PrintingInvokableUser e) {
        System.out.println(e.getString());
    }

}

public class PrintingInvokableUser extends InvokableUser<PrintingInvokableUser> {

    public PrintingInvokableUser() {
        super(PrintingInvokable::new);
    }

    public String getString() {
        return "( ͡° ͜ʖ ͡°)";
    }

}