有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java有一天JVM“void return type only”会成为一种自调用链接的新功能吗?

有一天JVM“void return type only”会成为一种自我调用链接的新功能吗

1)这意味着允许返回任何东西:但可能并不像评论员所说的那样好

若否,原因为何?为什么这是一个很好的理由,永远不允许下面

class A{
//    public Object a(){return null;}
  public void a(){}
}
class B extends A{
  @Override
    public String a(){return "";}; //error
}

2)这是关于自我呼叫链接,限制使用,将是更好/更安全/更清晰的选择

我为什么要那样?使用getThis() trick使setter像:new B().set1(1).set2(2).set3(3);一样链式链接

无效返回是如此无用,它不会破坏任何东西,因为它已经被所有东西忽略了

由于我们无法接触到大多数图书馆的设置者,也不想把他们都交出来,所以真正的交易将是让void(或者void?)我想你会成为我的目标甚至更好,成为一种新的限制类型,称为“?扩展Self”,让getThis()技巧成为JVM核心的一部分。所以这将是一个受限的用例,仅限于自链接调用

为什么高级语言(然后是汇编语言)不能允许这种协方差“违法”功能/选项?如果我们调用一个返回某个内容的方法并忽略/不捕获它,那么它的工作方式将等同于一个void返回! 因此,可以允许使用其他返回功能为曾经只有沙漠般的选项的地方带来新的曙光

所以,这是真正的交易,一个二传手返回无效将使我们没有选择:

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?


共 (2) 个答案

  1. # 1 楼答案

    因为继承的基本规律。具体而言,固体中的Liskov替换原理: https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
    “程序中的对象应可替换为其子类型的实例,而不会改变该程序的正确性。”

    通过更改返回类型,子类将不遵循此原则。调用b.a()不会返回void,而是返回一个字符串

    我想不出在返回void并随后被重写以返回其他内容的方法的特定情况下有什么具体问题,但这是一个非常奇怪的情况,我担心人们会滥用它,并且我的扩展了A的类d在d.A()上返回一个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时会发生什么

  2. # 2 楼答案

    Java确实支持协变返回类型。例如:

    class A {
        Object run() { ... }
    }
    
    class B {
        String run() {...}
    }
    

    因此,您的链式设置器示例可以使用覆盖(或泛型)。但是,生成的代码可能感觉不像惯用Java