/为什么Java需要有void
方法?参考:
任何声明为void的方法都不会返回值。
就我所能想到的,void
通过返回状态标志,被调用的对象或,将更好地服务于的每次使用null
。
这将使每个调用成为可分配的语句,并有助于构建器模式和方法链接。仅出于效果而调用的方法通常会返回布尔值或泛型Success
类型,或者在失败时引发异常。
/为什么Java需要有void
方法?参考:
任何声明为void的方法都不会返回值。
就我所能想到的,void
通过返回状态标志,被调用的对象或,将更好地服务于的每次使用null
。
这将使每个调用成为可分配的语句,并有助于构建器模式和方法链接。仅出于效果而调用的方法通常会返回布尔值或泛型Success
类型,或者在失败时引发异常。
Answers:
因为“此功能可以成功或失败并且具有足够的自我意识以至于可以分辨出差异”与“没有有关此功能效果的反馈”之间存在差异。没有void
,您将无休止地检查成功代码,并认为自己正在编写强大的软件,而实际上却什么也不做。
void
并没有说明方法或函数是否具有足够的自我意识,可以适当地抛出。
void
类型,所以Java的设计遵循了C语言家族的许多约定。Success
无论如何,您将如何处理“泛型类型”?实际上,表示成功的返回值在Java中的重要性甚至不如C中重要,因为Java具有表示失败的异常,而C却没有。Void
类型充当单元类型(例如,对于泛型),尽管它与void
(不同的是:每次您发明新的类型来修复在先前版本中弄乱的类型时,可爱的小猫都会死亡)不同。如果有人不熟悉单位类型,这是一个不错的介绍:en.wikipedia.org/wiki/Unit_type
null
(实际上这是唯一的选择),但是null是特殊的事情,Java中引用类型的任何值都可能为null(这是语言设计中的另一种错误)。而且,正如我之前说的,如果您使用Void
返回类型而不是void
mark,则Java编译器不是您的朋友。
null
。null
是大多数类型的成员这一事实与Void
单元类型是否相关。
语言具有类型的最初原因void
是因为像in中一样C
,语言的创建者不想像Pascal那样使过程和函数的语言语法不必要地复杂化。
那是最初的原因。
你的建议:
返回状态标志
那是不可以的。我们不使用状态标志。如果出现问题,我们会通过异常报告。
被调用的对象
流利的调用样式是最近的发展。今天,许多非常高兴地使用流利的程序员,如果不得不使用不支持该接口的接口,他们甚至会在创建Java时出生。
返回null
这将迫使您将一个方法声明为返回某种东西,而实际上它并未返回任何东西,因此对于正在查看接口以试图弄清楚它做什么的人来说,这将非常令人困惑。人们不可避免地会发明一些别无用处的类,表示“无返回值”,以便所有没有任何要返回的函数都可以返回对该类的空引用。那将是笨拙的。幸运的是,有一个解决方案,称为void
。这就是您问题的答案。
int
,因此关键字加入之后K&R,以指示“无返回类型”。
有些方法(例如)System.out.println
不会返回任何有用的信息,而纯粹是出于这种副作用而调用的。void
对编译器和代码阅读器来说是一个有用的指示,指示没有返回有用的值。
返回null
而不是void
意味着您将有NullPointerException
片刻时间将此值用于任何事物。因此,您将编译时错误换成运行时错误,这更糟。此外,您必须将返回类型定义为Object
,这会产生误导和混乱。(并且链接仍然不起作用。)
状态码通常用于指示错误情况,但是Java为此有例外。
this
无法从静态方法返回。
返回通用Success
对象将没有任何用处。
原因之一是,返回除以外的任何内容都可能会产生误导null
。例:
Arrays.sort(a)
返回什么?如果您认为a
应该返回该值以便可以将调用链接起来(这似乎是从您的问题来看,您的回答),则不再清楚返回值是原始对象的副本还是原始对象本身。两者都有可能。是的,您可以将其放入文档中,但是它很含糊,以至于您不应该首先创建歧义。
另一方面,如果您认为null
应该返回该值,那就是以下问题:返回值可能会为调用者提供哪些信息,以及为什么在不return null
传递任何信息时必须强制程序员进行编写。
而且,如果您返回的其他内容完全是荒谬的(例如的长度a
),那么使用该返回值确实会使您感到迷惑–只需考虑说int len = Arrays.sort(a)
而不是int len = A.length
!
return null;
-JVM也可以强制要求,如果控制权通过除显式return
或throw
语句之外的其他方法终止于函数的末尾,则将null
其隐式返回给调用方。IIRC C会执行此操作,但在这种情况下,返回值是未定义的(这将是当时用于返回值的位置中的任何值)。
return
声明,则不会出现“未定义的行为” 。而是,您得到一个编译器错误,告诉您您的错误。插入一个隐式return null;
方法比“未定义的行为”要好,但是不多。仅当返回类型没有意义时这才有用,但是当编译器从何处得出结论时,返回值没有意义void
呢?
return
真正不添加任何值……”,正如前面所说,编译器没有指示符,如果没有void
类型,则返回将不添加任何值。实际上是相反的,第一个假设是声明一个返回类型的方法想要return
该类型有用的东西。而且我们还没有讨论没有null
值的原始类型,因此,编译器注入的任何默认值都会与潜在有用的返回值范围冲突。
返回boolean
始终等于true
您建议的a不仅毫无意义(返回值不包含任何信息),而且实际上会产生误导。在大多数情况下,最好使用返回类型,其中仅携带的实际可用尽可能多的信息-这就是为什么在Java中,你必须boolean
为true
/ false
,而不是返回一个int
4个十亿可能的值。同样,boolean
在只有一个可能值的情况下返回具有两个可能值的“ a”(“一般成功”)会产生误导。
这也将增加不必要的性能开销。
如果仅将方法用于其副作用,则没有任何要返回的内容,并且返回类型void
恰好反映了这一点。潜在的罕见错误可以通过异常发出信号。
可以改进的一件事是制作void
一个实际的类型,例如Scala的Unit
。这将解决一些问题,例如处理泛型。
List.add
确实会返回true
,但这是为了与的更广泛的合同兼容Collection.add
,因此Set.add
可能会返回true
或false
。
Java是一种相对古老的语言。在1995年(当它创建时),此后不久,程序员非常担心进程控制处理器的时间以及内存的消耗。返回void将消除函数调用的几个时钟周期和一些内存消耗,因为您不必将返回值放在堆栈上,并且随后也不必删除它。
高效的代码不会给您带来您永远不会使用的东西,因此将void放入具有无意义的返回值的东西中要比返回成功值要好得多。
我已经读过一些论点,建议第二种选择(return this
)应该是方法而不是void
。这是一个很好的主意,但是在创建Java时,生成器风格的方法并不流行。如果它当时和现在一样流行,那可能就是采取的方法。返回null
是一个非常糟糕的主意IMO。我希望null
根本不用语言。
现在的问题是,如果方法返回其自身类型的实例,则不清楚该对象是新对象还是相同对象。通常,它并不重要(或不应该),但其他时候确实很重要。我想可以将语言更改为隐式返回this
void方法。我目前唯一能想到的问题是,如果以后更改方法以返回相同类型的新对象,则不会有编译警告,但这可能没什么大不了的。当前的类型系统现在不在乎这些类型的更改。它如何与继承/接口交互需要一些考虑,但是它将允许没有构建器样式的旧API像它们一样容易被调用。
null
不是语言的一部分,人们将使用各种各样的哨兵值,这意味着“请忽略此参数/返回值,它不包含任何明智的值”。问题null
不在于事物本身,而在于它往往被错误地使用。我敢打赌,只有null
用大量的自定义解决方案替换标准化后,这个问题才会被夸大,在每种解决方案中,每个实现的行为都将像静默忽略用法一样,或者抛出特殊的异常而不是标准的空指针异常,等等
null
是适当的可选类型(例如,Maybe
在Haskell中)。Java中空值的问题在于,没有一种明智的方法可以立即确定一个值在实践中是否可以为空。这会导致以下两种情况:不必要的防御性编程(在无意义的地方检查空值,从而增加代码中便便的百分比),以及生产中意外的NPE(如果忘记检查需要在哪里)。是的,它可以通过注释部分解决,但它们是可选的,并非始终处于选中状态等。因此,它们不会在第三方代码的边界上为您省钱。
null
为此可以很好地工作(很好=简单),但是具有可靠语义的标准化可选值绝对是另一个很好的选择(很好=安全)。
另一个方面:
Java是具有相当严格功能的静态语言。这意味着严格确定了许多其他语言(c / f Ruby,Lisp等)中相当开放或动态的内容。
这是一般的设计决策。“为什么”很难回答(好吧,因为语言的设计者认为这会很好!)。“针对”的含义很明确:它使编译器能够检测到很多错误,这对于任何一种语言来说通常都是相当不错的功能。其次,它使语言推理相对容易。例如,用Java语言(的子集)创建形式正确性证明相对容易;相比之下,在像Ruby等人的动态语言中这几乎是不可能的。
这种想法渗透到了语言中,例如,方法可能抛出的可能异常的强制声明,interface
vs 。的单独类型,class
以避免模棱两可的多重继承,等等。就其本质而言(一种静态命令式OOP现实语言,重点是编译时错误处理),这些东西实际上是相当优雅和强大的。它们比理论(科学)语言更接近,而理论(科学)语言是专门为探索这些问题而设计的,比以前的任何其他现实世界语言(当时请注意)。
所以。具有严格的void
类型是一条明确的消息:该方法在句点期间不返回任何内容。就是这样。通过强制执行替换它总是返回某些东西将导致更多的动态行为(例如在Ruby中,每个 def总是具有显式或隐式的返回值),这对于可证明性和推理是不利的;或通过使用此处的其他机制将其膨胀。
(和NB,红宝石(例如)处理此不同,它的解决方案仍然是完全一样接受 Java的,因为它有一个完全不同的理念。例如,它完全抛出可证性与合理性窗外,同时把一大重点语言的极高表达能力。)