Java中不同返回类型的重载?
Posted
技术标签:
【中文标题】Java中不同返回类型的重载?【英文标题】:Overload with different return type in Java? 【发布时间】:2011-01-27 05:48:16 【问题描述】:为什么不能仅仅通过改变返回类型来重载一个函数?这会在 Java 的未来版本中发生变化吗?
顺便说一下,仅供参考,这在C++中可以吗?
【问题讨论】:
Function overloading by return type?的可能重复 KNU,另一个答案的不同之处在于它以一般性的非语言特定术语提出问题。同样有趣的是,其他问题的接受答案更进一步,指定 Java JVM 确实允许通过内部操作来完成。 【参考方案1】:你不能在 Java 中做到这一点,你也不能在 C++ 中做到这一点。理由是仅返回值不足以让编译器确定要调用哪个函数:
public int foo() ...
public float foo() ..
...
foo(); // which one?
【讨论】:
我一直认为,如果我们执行类似 int i = foo() 或 float f = foo() 之类的操作,它会知道是哪一个,但如果该语句只是编译器不会使用的函数不知道。我知道了。谢谢。 @nunos 即使它是 float f = foo() 编译器也无法弄清楚,因为两个 int 都是浮点数的有效输入。比较 float f = 7; (7 是浮点数还是整数?) @NomeN 但是你的陈述表明 func(int i) 和 func(float i) 对于编译器来说是无法区分的——我们都知道这不是真的。 Oded 给出了真正的原因(见下一个答案) - 它与方法的签名有关。而且,顺便说一句。 7 绝对是整数,而 7.0 或 7f 是浮点数;-) 7.0 不是float
,而是double
。
foo();
没有返回类型将是模棱两可的事实不一定是禁止它作为重载的理由。有些参数可能会导致歧义(例如foo(null);
),但这并不会使重载本质上无效。【参考方案2】:
原因是Java中的重载只允许用于具有不同签名的方法。
返回类型不是方法签名的一部分,因此不能用于区分重载。
请参阅 Java 教程中的 Defining Methods。
【讨论】:
但是为什么返回类型不是签名的一部分 哦,“只是因为”!我明白了。 返回类型是方法签名的一部分。只需查看类反汇编。 这真的不是@konmik - 不是方法重载的规则。试试吧。相同的方法名,相同的参数类型,相同的顺序,不同的返回类型。不会编译。 是的,因为返回类型不是签名的一部分。签名是 - 方法的名称 + 其参数的类型和顺序。阅读我在回答中提供的链接:“上面声明的方法的签名是:calculateAnswer(double, int, double, double)
”。看到返回类型不包括在内,@konmik。【参考方案3】:
在 Java 5.0 之前,当您重写方法时,参数和返回类型必须完全匹配。在 Java 5.0 中,它引入了一种称为协变返回类型的新工具。您可以覆盖具有相同签名的方法,但返回返回对象的子类。换句话说,子类中的方法可以返回一个对象,该对象的类型是该方法返回的类型的子类,在超类中具有相同的签名。
【讨论】:
当我第一次看到这个时,我感到很困惑。感谢您解释为什么会这样! 重载和覆盖是不同的。重载不(必然)涉及继承 对于 Java 新手来说,这个答案听起来可能会产生误导,因为它根本与 重载 无关,它是 覆盖 - 完全是另一回事。 【参考方案4】:Overloaded
java 中的方法可能具有不同的返回类型,因为参数也不同。
查看示例代码。
public class B
public String greet()
return "Hello";
//This will work
public StringBuilder greet(String name)
return new StringBuilder("Hello " + name);
//This will not work
//Error: Duplicate method greet() in type B
public StringBuilder greet()
return new StringBuilder("Hello Tarzan");
【讨论】:
基本上不考虑返回类型,只考虑参数,悲伤但真实【参考方案5】:编译器在区分方法时不考虑返回类型,因此即使返回类型不同,也不能声明两个签名相同的方法。
【讨论】:
【参考方案6】:重载方法时返回类型无关紧要。我们只需要确保没有歧义!
Java 知道调用哪个方法的唯一方法是区分参数列表的类型。如果编译器允许两个具有相同名称和相同参数类型的方法,则无法确定它应该调用哪一个。
【讨论】:
当然,编译器只根据返回值就很容易区分调用哪个重载函数。因此int result = foo();
与float result = foo();
不同。【参考方案7】:
编译器在区分方法时不考虑返回类型,因此即使返回类型不同,也不能声明两个签名相同的方法。
如果你知道函数执行,那么你就会知道,当我们调用函数时,定义部分会执行,最后我们需要 return 语句,因此我们可以说 return 在函数的整个定义之后,这就是为什么如果有是两个或多个具有相同名称和相同类型且编号相同的函数。然后在调用时编译器将如何知道要调用哪个参数,因为函数名称和参数是相同的。调用时首先关注的是参数和函数名,函数定义完成后,最后处理return语句。
编译时错误优于运行时错误。因此,如果您声明具有相同参数的相同方法,java 编译器会呈现编译器时间错误。
【讨论】:
这与接受的答案有何不同? (也是编译时错误的原因是因为编译器无法确定调用哪个方法,那么它应该如何生成正确的可执行代码)【参考方案8】:重载方法是与任何其他同名方法完全不同的方法。重载只不过是重用名称。
【讨论】:
【参考方案9】:不可能,那样你只能通过没有参数或参数的数据类型来重载
【讨论】:
以上是关于Java中不同返回类型的重载?的主要内容,如果未能解决你的问题,请参考以下文章