繁体   English   中英

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

[英]How would I use generics in Java to create a generic interface that defines a method that only accepts the implementation as a parameter?

有没有一种方法可以在接口中定义一个方法,在其中可以将实现键入到实现类中? 这是我最初尝试解决该问题的具体示例,但我会指出失败的地方。

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

我认为用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);
     }
}

每个类只能具有方法boolean approxEquals(T that)单个实际实现,因此,您必须为每个类确定是否要使用该方法精确地表示该类(例如MyDecimal2 ),或者希望它能够处理更大的范围。类型-一些父类型(例如MyDecimal3 )。 几乎总是希望它完全处理该类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM