Java泛型类型

vrm*_*vrm 7 java generics

当我有一个界面

public interface Foo<T> {
    T someMethod();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法确保当某个类实现此接口时,泛型类型是相同的实现类.

例如:

public class Bar implements Foo<Bar>  {
    Bar someMethod() {
        return new Bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*ung 23

是的,这可以做到(有点;见下文).(在C++世界中,这被称为" 奇怪的重复模板模式 ",但它也适用于Java):

public interface Recur<T extends Recur<T>> {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

(注意第二次提到T.这是CRTP的一个重要部分.)

此外,这是如何java.util.Enum定义的,因此调用的枚举类型Foo必须派生自Enum<Foo>,因此它在Java中也不是一种不常见的模式.


我想说上面是故事的结尾,但是Tangens在他们的修订版中正确指出它并不完全健壮,而且与他们的回答并没有完全不同.

Recur<T>我所拥有的Recur<?>解决方案与tangens 的解决方案之间存在一个区别(我能想到):

public interface Recur<T extends Recur<T>> {
    T foo();
}

class A implements Recur<B> {
    @Override
    public B foo() {
        return new B();
    }
}

class B implements Recur<A> {
    @Override
    public A foo() {
        return new A();
    }
}
Run Code Online (Sandbox Code Playgroud)

有了<T>,上面就不会编译; 有<?>,它会.但那只是分裂的头发; 它不会改变tangens的中心点,即给定已经有效的Recur实现,您可以使后续实现使用已经有效的类型,而不是自身.我仍然说这是有价值的东西,但这不仅仅是一个比tangens的答案更值得的东西.

最后,如果可以的话,继续并提出tangens的回答.(tangens,你应该触摸你的帖子,这样我也可以投票给你.)他们有一个非常好的观点,我很抱歉,我第一次错过了它.谢谢,tangens!


tan*_*ens 14

不,你不能参考实现类.你能做的最好的事情是:

public interface Foo<T extends Foo<?> > {
    T someMethod();
}
Run Code Online (Sandbox Code Playgroud)

这样做,您可以确保someMethod()返回实现的对象Foo.


编辑:

即使使用这样的接口定义:

public interface Foo<T extends Foo<T > > {
    T someMethod();
}
Run Code Online (Sandbox Code Playgroud)

您可以定义一个类 Bar2

public class Bar2 implements Foo<Bar2 > {
    @Override
    public Bar2 someMethod() {
        return new Bar2();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以定义一个Bar实现Foo但不返回的类,Bar但是Bar2:

public class Bar implements Foo<Bar2 > {
    @Override
    public Bar2 someMethod() {
        return new Bar2();
    }
}
Run Code Online (Sandbox Code Playgroud)

最初的问题是,你是否可以像对待那样准备使用界面Bar.

答案是:不.


编辑:

Angelika Langer给出了一个很好的解释,我如何解密"Enum <E extends Enum <E >>"?

  • 我添加了一个例子,为什么@ chris-jester-young的答案并不比我的好. (2认同)