如何在Java中使用泛型来创建一个泛型接口,该接口定义一个只接受实现作为参数的方法?

如何在Java中使用泛型来创建一个泛型接口,该接口定义一个只接受实现作为参数的方法?,java,generics,Java,Generics,有没有一种方法可以在接口中定义一个方法,在接口中实现可以被类型化到实现类?下面是我最初尝试解决这个问题的一个具体例子,但我会指出它失败的地方 public interface ErrorMeasurable<T extends ErrorMeasurable<T>> { // I want every implementation of this method to accept // the implementing type as a parame

有没有一种方法可以在接口中定义一个方法,在接口中实现可以被类型化到实现类?下面是我最初尝试解决这个问题的一个具体例子,但我会指出它失败的地方

public interface ErrorMeasurable<T extends ErrorMeasurable<T>> {
     // I want every implementation of this method to accept
     // the implementing type as a parameter. I'm willing to accept
     // that programmers can maliciously type it to something else
     // that meets the type boundary.  I'm not willing to accept
     // polymorphic usage to be verbose or strange as the below example shows.
     boolean approxEquals(T that);
}

// This works...
public class MyDecimal implements ErrorMeasurable<MyDecimal> {
     boolean approxEquals(MyDecimal that) { ... }
}

// But polymorphism doesn't work well... 
public interface MyNumber<T extends ErrorMeasurable<T>> implements ErrorMeasurable<T> {
     boolean approxEquals(T that) { ... }
}

public class MyDecimal2 implements MyNumber<MyDecimal> {
     boolean approxEquals(MyDecimal that) { ... }
}

public class UsesNumbers {

     // PROBLEM 1: the type parameter is unbound.
     MyNumber rawNumber1, rawNumber2;

     // PROBLEM 2: This binds the type parameter but it is hard to understand why its typed to itself
     MyNumber<MyNumber> boundNumber1, boundNumber2;

     void example() {
          // PROBLEM 3: There will be a compiler warning about the raw types.
          rawNumber1.approxEquals(rawNumber2);

          // Works without warnings, see PROBLEM 2 though.
          boundNumber1.approxEquals(boundNumber2);
     }
}
公共接口错误{
//我希望此方法的每个实现都能接受
//实现类型作为参数。我愿意接受
//程序员可以恶意地将其键入其他内容
//这符合类型界限。我不愿意接受
//多态用法可能冗长或奇怪,如下面的示例所示。
布尔逼近等式(T);
}
//这很有效。。。
公共类MyDecimal实现了ErrorMeasured{
布尔逼近相等(MyDecimal){…}
}
//但是多态性并不好用。。。
公共接口MyNumber实现了可测量的错误{
布尔逼近等式(T){…}
}
公共类MyDecimal2实现MyNumber{
布尔逼近相等(MyDecimal){…}
}
公共类使用次数{
//问题1:类型参数未绑定。
我的号码rawNumber1,rawNumber2;
//问题2:这会绑定类型参数,但很难理解为什么它是类型化的
MyNumber boundNumber1、boundNumber2;
void示例(){
//问题3:将出现有关原始类型的编译器警告。
rawNumber1.近似相等(rawNumber2);
//在没有警告的情况下工作,但请参见问题2。
boundNumber1.近似相等(boundNumber2);
}
}

我不认为用Java中当前级别的泛型可以实现您的愿望。

您无法阻止其他人使用泛型作为原始类型,但这至少会发出警告。若并没有警告,代码保证是类型安全的

对于问题2,您可能想要的是:

public interface MyNumber<T extends MyNumber<T>> implements ErrorMeasurable<T> {
     boolean approxEquals(T that) { ... }
}

public class MyDecimal2 implements MyNumber<MyDecimal2> {
     boolean approxEquals(MyDecimal2 that) { ... }
}

public class MyDecimal3 extends MyDecimal2 {
     boolean approxEquals(MyDecimal2 that) { ... }
}

public class UsesNumbersClass<T extends MyNumber<T>> {
     T boundNumber1, boundNumber2;

     void example() {
          boundNumber1.approxEquals(boundNumber2);
     }
}

public class UsesNumbersOnlyMethod {
     <T extends MyNumber<T>> void example(T boundNumber1, T boundNumber2) {
          boundNumber1.approxEquals(boundNumber2);
     }
}
公共接口MyNumber实现了可测量的错误{
布尔逼近等式(T){…}
}
公共类MyDecimal2实现MyNumber{
布尔逼近相等(MyDecimal2){…}
}
公共类MyDecimal3扩展了MyDecimal2{
布尔逼近相等(MyDecimal2){…}
}
公共类使用成员类{
T boundNumber1,boundNumber2;
void示例(){
boundNumber1.近似相等(boundNumber2);
}
}
公共类使用mbersonlymethod{
无效示例(T boundNumber1,T boundNumber2){
boundNumber1.近似相等(boundNumber2);
}
}

每个类只能有一个方法
布尔近似相等(T that)
的实际实现,因此您必须为每个类决定是否希望该方法准确地表示该类(如
MyDecimal2
),或者希望它能够处理更广泛的类型—某些父类型(如
MyDecimal3
)。您几乎总是希望它能够准确地处理该类。

您知道,“不是一个真正的问题”=/=“我不理解这个问题”。感谢Sarmun,我的意思是问题1和3构成了一个“错误”的解决方案,我想避免,但不一定解决,因为没有办法强制使用非原始泛型类型。你提到的一个具体类示例的子类不是我试图解决的那个。UseSumbersOnlymethod与我希望在ErrorMeasured下使用类型层次结构的方式类似。您能解释一下您想做什么吗?我的答案中没有涉及到这一点?主要的一点是,如果您有两个ErrorMeasured实例,您不知道它们是否可以检查approxEquals,除非它们是完全相同的类型。而且,您只能通过UseSNumberClass或UseSNumberOnlyMethod(类或方法上的类型绑定)强制