我正在处理这样一种情况,即我希望拥有类型的泛型
MyGeneric<T extends A | B>
即镜像的东西
MyGeneric<T extends A & B>
最后一个是允许的,给定B是一个接口;不接受B作为类的原因是Java不支持显式的多重继承。
从接受两种类型之一的Generic类中,我得到了一个确认,即我对泛型的OR子句的猜测对于Java来说是不可接受的。这意味着,无论B是类还是接口,我对OR子句的猜测在语法上都是不正确的。所以我想知道Java为什么不支持这一点。还有比"不执行"更有力的理由吗?
---编辑---
当然,在很多情况下,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> {...}
而且很酷。
但是,假设您创建了一个"YourCommand"类。如果它与MyAbstractCommand无关,我将被迫复制报告的代码,或者创建一个由两个抽象命令实现的公共接口,或者让YourCommand扩展MyAbstract Command。如果支持OR子句,我可以将YourCommand添加到泛型的可接受参数类型列表中。
如果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?
}
Ceylon通过联合类型实现了这一点。由于JVM堆栈中存在这种语言,这意味着没有技术限制会禁止这种功能(我也想不出这样的限制)。尽管如此,有人可能会认为这样的功能不太可取,尤其是当语言支持mixin/ttrates/default方法时。
就我个人而言,我更喜欢使用接口分离原则和交集类型。这在可读性和可维护性方面要干净得多。当然,这并不总是可能的,尤其是在与第三方图书馆合作时。因此,这不是一个坏主意(我想Redhat的人也这么认为)。
因此,把这两个论点结合起来,就可以回答你的问题:
还有比"不执行"更有力的理由吗?
没有技术限制,但这不是一个好主意,因此它不是一个优先事项,而且可能不会持续很长时间。