为什么Java泛型不支持通配符的OR子句?

时间:2014-10-26 11:00:44

标签: java generics

我正在应对一种情况,我希望拥有类型的通用

MyGeneric<T extends A | B>

即。镜像的东西

MyGeneric<T extends A & B>

。如果B是接口,则允许最后一个;不接受B作为类的原因是Java不支持多继承显式

Generic class that accepts either of two types我得到确认,我对Java的OR子句的猜测是不可接受的。这意味着我对OR子句的猜测在语法上是不正确的,无论B是类还是接口。 所以我想知道为什么Java不支持这个。是否有更强的理由而不是&#34;未实施&#34;?

--- --- EDIT

当然有很多情况下OR条款可能引起怀疑(见评论和答案),但看看我的情况:

public abstract class MyAbstractTask<T extends MyAbstractCommand> {
    @Override
    final protected void onPostExecute(String result) {
        super.onPostExecute(result);
        if (result != null) {
           T response = null;

           Gson gson = new Gson();
           response = gson.fromJson(result, clazz);7
           postProcess(response);
        }
    }
    abstract void postProcess(T task);
}

在这种情况下,我正在应用模板方法模式+命令模式。所以T是命令,postProcess负责运行它。

现在我可以拥有像

这样的东西
public class MyTask extends MyAbstractTask<MyCommand> {...}

很酷。

但是,假设您创建了一个&#34; YourCommand&#34;类。如果它与MyAbstractCommand无关,我不得不复制报告的代码或创建由两个抽象命令实现的公共接口或让YourCommand扩展MyAbstractCommand。如果支持OR子句,我可以将YourCommand添加到我的通用的接受参数类型列表中。

2 个答案:

答案 0 :(得分:5)

如果java泛型确实支持OR子句,那么注释中的问题如何:

<T extends Runnable | Callable<?>> void fun(T wtf)throws Exception{
      wtf.run(); // is this a compile time error?
      wtf.call(); // is this a compile time error?
}

void main(Runnable runnable, Callable<?> callable){
      fun(runnable); // is this a runtime error?
      fun(callable); // is this a runtime error?
}

答案 1 :(得分:1)

锡兰用union types实现了这个目标。由于这种语言存在于JVM堆栈中,这意味着没有技术限制可以禁止这样的功能(我也不能想到这样的限制)。然而,人们可能会争辩说这样的特征不太理想,特别是当语言支持mixins / traits / default方法时。

我个人更喜欢使用interface segregation principle和交集类型的用法。这在可读性和可维护性方面更加清晰。当然,这并非总是可行,尤其是在与第三方库合作时。因此,这不是一个坏主意(我猜Redhat的人也这么认为)。

所以要将两个参数组合成你问题的答案:

  

是否有更强的理由而不是&#34;未实施&#34;?

没有技术限制,但这不是一个好主意,因此它不是优先考虑的事情,并且可能不会持续很长时间。