有一天JVM" void返回类型只有"成为一个自我呼唤链接新能力?
1)这将是允许返回任何内容:但可能不太好,正如评论者所说
如果没有,为什么?为什么永远不允许在下面这是一个很好的理由?
class A{
// public Object a(){return null;}
public void a(){}
}
class B extends A{
@Override
public String a(){return "";}; //error
}
2)这是关于自我通话链接,限制使用,会更好/更安全/更清晰的选择
为什么我想要那个?让setter像new B().set1(1).set2(2).set3(3);
使用getThis() trick
void return 是如此无用,它会破坏任何东西,因为它已被所有东西忽略了!
由于我们无法访问大多数库的设置者,并且不想将它们全部分开,真正的优点是让void(或Void?)成为Object我猜。 甚至更好,成为一种名为"的新限制类型?延伸自我"让getThis()技巧成为JVM核心的一部分。。所以这将是一个受限制的用例,只能进行自我链接调用。
为什么高级语言(然后是汇编语言)不能允许这种协方差"法律破坏"功能/选项?如果我们调用一个返回某个东西而忽略/不捕获它的方法,它将等效于void返回! 因此,否则可以允许其他功能为新的光线带来新的亮点,除了大量选择之外什么都没有。
所以,这是真正的交易,其中一个返回void的setter会让我们无法选择:
class A<SELF extends A>{
// public void set(){} //this one leaves us no options
public SELF set(){return getThis();}
public SELF getThis(){return (SELF)this;}
}
class B extends A<B>{
@Override public B set(){return getThis();}
@Override public B getThis(){return this;}
}
基本上,我不是在寻找意见,我正在寻找一个很好的理由/解释。
所以,我知道除了这个问题的要求之外,我还在进一步争论:Why is void not covariant in Java?
答案 0 :(得分:1)
由于继承的基本规律。具体来说,SOLID中的Liskov替换原则:
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
“程序中的对象应该可以替换为其子类型的实例,而不会改变该程序的正确性。”
通过更改返回类型,子类不会遵循此原则。调用b.a()
不会返回void,而是返回String。
我无法想到返回无效的方法的特定情况下的任何具体问题,以后会被覆盖以返回其他内容,但这是一个奇怪的情况,我会担心人们会滥用它而我的D类扩展A会在Da()上返回一个int,现在每个人都感到困惑。
因为当我告诉我的其他程序员我正在调用A的某个子类的方法a()时,他们知道它将返回什么。
class A{
// public Object a(){return null;}
public void a(){}
}
class B extends A{
@Override
public String a(){return "";}; //error
}
class C extends A{
@Override
public int a(){return 0;}; //error
}
现在方法a()有什么作用?我如何以合理的方式与我的团队沟通这种方法?
现在想象我有这个:
List<A> listOfAs = new ArrayList<>();
当我致电listOfAs.get(0).a() / 2
时会发生什么?
答案 1 :(得分:0)
Java确实支持协变返回类型。例如:
class A {
Object run() { ... }
}
class B {
String run() {...}
}
因此,您的链式setter示例可以使用覆盖(或泛型)。但结果代码可能不像惯用Java。