Java 编译的非void方法中缺少return语句
我遇到了这样一种情况,非void方法缺少return语句,代码仍在编译。Java 编译的非void方法中缺少return语句,java,c#,oop,Java,C#,Oop,我遇到了这样一种情况,非void方法缺少return语句,代码仍在编译。 我知道while循环之后的语句是不可访问的(死代码),永远不会执行。但是为什么编译器甚至不警告返回某些东西呢?或者为什么一种语言允许我们有一个非void方法,它有一个无限循环,并且不返回任何东西 public int doNotReturnAnything() { while(true) { //do something } //no return statement } 如果我在
我知道while循环之后的语句是不可访问的(死代码),永远不会执行。但是为什么编译器甚至不警告返回某些东西呢?或者为什么一种语言允许我们有一个非void方法,它有一个无限循环,并且不返回任何东西
public int doNotReturnAnything() {
while(true) {
//do something
}
//no return statement
}
如果我在while循环中添加break语句(甚至是条件语句),编译器会抱怨臭名昭著的错误:方法在Eclipse中不返回值
,在visualstudio中并非所有代码路径都返回值
public int doNotReturnAnything() {
while(true) {
if(mustReturn) break;
//do something
}
//no return statement
}
Java和C#都是如此。编译器知道
while
循环永远不会停止执行,因此方法永远不会结束,因此不需要return
语句。Java编译器足够聪明,可以找到无法访问的代码(while循环之后的代码)
由于它不可访问,因此在那里添加return
语句没有意义(在之后,而结束)
如果
public int get() {
if(someBoolean) {
return 10;
}
else {
return 5;
}
// there is no need of say, return 11 here;
}
由于布尔条件someBoolean
只能计算为true
或false
,因此不需要在if-else
之后显式提供返回值,因为该代码是不可访问的,Java也不会对此抱怨。如果您的循环是在一个常量上执行的,编译器知道这是一个无限循环,这意味着该方法无论如何都无法返回
如果使用变量-编译器将强制执行以下规则:
这不会编译:
// Define other methods and classes here
public int doNotReturnAnything() {
var x = true;
while(x == true) {
//do something
}
//no return statement - won't compile
}
Java规范定义了一个称为不可访问语句
的概念。不允许在代码中包含无法访问的语句(这是编译时错误)。您甚至不允许在while之后使用return语句(true);语句。Awhile(真)
statement根据定义使以下语句无法访问,因此不需要return
语句
请注意,虽然在泛型中是不可判定的,但不可到达语句的定义比停止更严格。它决定了一个程序绝对不会停止的非常具体的情况。理论上,编译器无法检测所有无限循环和无法访问的语句,但它必须检测规范中定义的特定情况(例如,while(true)
case)编译器足够聪明,可以发现while
循环是无限的
因此编译器无法为您思考。它无法猜出你为什么写那段代码。这表示方法的返回值。如果不处理方法的返回值,Java不会抱怨
所以,要回答你的问题:
编译器分析您的代码,发现没有执行路径会导致从函数末尾掉下来,然后以OK结束
可能存在无限循环的正当理由。例如,许多应用程序使用无限主循环。另一个例子是web服务器,它可能无限期地等待请求。Visual studio有智能引擎来检测您是否键入了返回类型,那么它应该在函数/方法中有一个带有的返回语句
在PHP中,如果没有返回任何内容,则返回类型为true。如果未返回任何内容,则编译器获取1
至此
public int doNotReturnAnything() {
while(true) {
//do something
}
//no return statement
}
编译器知道,虽然语句本身有无限的性质,所以不要考虑它。如果在while表达式中编写一个条件,php编译器将自动得到true
但是在VS的情况下,它将返回堆栈中的错误。您的while循环将永远运行,因此不会出现while;它将继续执行。因此,while{}的外部部分是不可访问的,并且没有写返回或不返回的意义。编译器具有足够的智能,能够找出哪些部分是可访问的,哪些部分是不可访问的
例如:
public int xyz(){
boolean x=true;
while(x==true){
// do something
}
// no return statement
}
上面的代码不会编译,因为在while循环体中可能会修改变量x的值。因此,这使得while循环的外部部分可以访问!因此,编译器将抛出一个错误“找不到返回语句”
编译器没有足够的智能(或者说是懒惰的;)来判断x的值是否会被修改。希望这能清除一切。为什么编译器甚至不警告返回某些内容?或者为什么语言允许我们使用具有无限循环的非void方法而不返回任何内容
此代码在所有其他语言中也有效(可能除了Haskell!)。因为第一个假设是我们“有意”编写一些代码
在某些情况下,这段代码可能完全有效,例如,如果您打算将其用作线程;或者,如果它正在返回一个任务
,您可以根据返回的int值执行一些错误检查,而int值不应返回。在任何情况下,函数都可以在不返回适当值的情况下到达其终点。因此,编译器没有什么可抱怨的
为什么一种语言允许我们有一个非void方法,它有一个无限循环,并且不返回任何东西
public int doNotReturnAnything() {
while(true) {
//do something
}
//no return statement
}
非void方法的规则是每个返回的代码路径都必须返回一个值,并且该规则在您的程序中得到满足:返回值的零代码路径中的零代码路径确实返回一个值。规则不是“每个非void方法必须有一个返回的代码路径”
这使您能够编写存根方法,如:
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
这是一种非无效的方法。为了满足界面要求,它必须是一种非void方法。但将此实现定为非法似乎很愚蠢,因为我
// I compile just fine!
public boolean testReturn()
{
final boolean condition = true;
while (condition)
{
return true;
}
}