我想知道在Java中专门化泛型类型的选项是什么,即在模板化的类中对某些类型进行特定的覆盖.
在我的例子中,我是一个泛型类(类型为T)通常返回null,但返回""(空字符串),当T是String类型时,或者当它是Integer类型时返回0(零)等.
仅提供方法的类型特定重载会产生"方法不明确"错误:
例如:
public class Hacking {
public static void main(String[] args) {
Bar<Integer> barInt = new Bar<Integer>();
Bar<String> barString = new Bar<String>();
// OK, returns null
System.out.println(barInt.get(new Integer(4)));
// ERROR: The method get(String) is ambiguous for the type Bar<String>
System.out.println(barString.get(new String("foo")));
}
public static class Bar<T> {
public T get(T x) {
return null;
}
public String get(String x) {
return "";
}
}
}
Run Code Online (Sandbox Code Playgroud)
是使用特定类型子类化泛型类的唯一选项(请参阅以下示例中的StringBar?
public static void main(String[] args) {
Bar<Integer> barInt = new Bar<Integer>();
StringBar …Run Code Online (Sandbox Code Playgroud) 首先,一点背景(如果不感兴趣,可以跳过一点).我很生气,很困惑!这应该是一个非常简单的用例,事实上我的代码已经用Eclipse JDT编译器编译得很好,所以直到现在我一直在配置Maven以确保这样做.尽管它不能用Oracle JDK和OpenJDK编译,但是我一直在困扰我,因为我认为它可能实际上是我的代码的问题,所以我再次研究它.
我想也许这个bug是在JDT编译器中允许它编译的,而不是Oracle JDK和OpenJDK因为不允许它,我也用它来测试这两个.有问题的原始代码要复杂得多,所以我很难看到问题出在哪里,事实上,我很惊讶地发现在不编译的情况下可以减少这个问题的程度.
Eclipse JDT编译器或Oracle JDK和OpenJDK都有一个非常重要的(imho)错误.
这是相关代码的相当小的表示.(Anything的类型绑定可以被任何接口替换,编译器行为不会改变):
public class Bug<X extends Property<?, ?> & Anything> {
}
interface Property<C, S extends C> extends PropertyConst<C> {
@Override
public S get();
}
interface PropertyConst<C> {
public C get();
}
interface Anything {
}
Run Code Online (Sandbox Code Playgroud)
总而言之,我认为这应该编译得很好,但Oracle JDK 7&8和OpenJDK 7不同意.它使用Eclipse Juno为我编译.
当使用这些编译器中的任何一个编译时,上面的代码给出类似于以下错误的东西,但是对于JDT编译器工作得很好:
Bug.java:3: error: types PropertyConst<?> and Property<?,?> are incompatible; both define get(), but with unrelated return types
public class Bug<X extends Property<?, ?> & Anything> {
^
1 …Run Code Online (Sandbox Code Playgroud)