Java 重载Math.sqrt:重载方法似乎隐藏了原始方法
正在尝试为Java 重载Math.sqrt:重载方法似乎隐藏了原始方法,java,static,methods,overloading,Java,Static,Methods,Overloading,正在尝试为int类型重载java.lang.Math.sqrt静态方法: import static java.lang.Math.sqrt; class Test { private static double sqrt(int n) { return sqrt(1.0 * n); } public static void main(String[] args) { System.out.println(sqrt(1)
int
类型重载java.lang.Math.sqrt
静态方法:
import static java.lang.Math.sqrt;
class Test
{
private static double sqrt(int n)
{
return sqrt(1.0 * n);
}
public static void main(String[] args)
{
System.out.println(sqrt(1));
}
}
出现了一个奇怪的错误:
Test.java:7: sqrt(int) in Test cannot be applied to (double)
return sqrt(1.0 * n);
^
1 error
但是当显式引用java.lang.Math.sqrt
方法时,一切都很顺利:
class Test
{
private static double sqrt(int n)
{
return Math.sqrt(1.0 * n);
}
public static void main(String[] args)
{
System.out.println(sqrt(1));
}
}
使用的编译器是标准的javac,版本1.6.0_16
因此,问题是:
Test中的sqrt(int)不能应用于(double)
如果要调用Math.sqrt,请使用其他名称重命名函数:
private static double mysqrt(int n)
{
return sqrt(1.0 * n);
}
只能重载同一类中的方法。也就是说,如果导入另一个类的静态方法,然后用相同的名称定义自己的方法,则不会出现重载解析。方法的导入版本将被忽略 关于指定此行为的位置:语言规范定义了重载: 如果一个类的两个方法(无论是在同一个类中声明的,还是都由一个类继承的,或者一个声明的和一个继承的)具有相同的名称,但签名不是重写等价的,则称该方法名为重载 请注意,它表示“一个类的两个方法”。因此,根本不考虑从另一个类导入的方法 因此,由于您的定义不是Math.sqrt的重载,因此它会按照以下方式对其进行阴影处理: 名为n的方法的声明d在d在整个d范围内出现的点处,隐藏了封闭范围内名为n的任何其他方法的声明
在第一个调用中,所引用的方法是您返回的方法,该方法期望int作为其参数,但您正在向其发送double。所以它给出了一个编译器错误
但是在第二个调用中,您指的是Math.sqrt(),它工作得很好。您实际上并没有重载。事情因模棱两可而悬而未决;编译器看到
返回sqrt(1.0*n)
,它假定您正在谈论类测试中的sqrt(int)
函数,而不是lang.Math
中的函数。这是更好的行为;毕竟,您可能不希望每次尝试调用成员函数时都必须指定class.method
。编译器没有解决这个问题,因为在您的特定情况下,它假设您犯了错误,并且没有意识到您打算在lang.Math
中调用sqrt
,这很正常。
通过编写此代码,您没有以任何方式重载Math.sqrt
方法,您只是将Test.sqrt(int)
定义为一个参数
然后是你的错误信息的问题
定义Test.sqrt方法时,会重载(在此类中)所做的静态导入
这样,当调用SqRT(1 *N)时,编译器会尝试调用一个加倍的Stest.qrt(int),这显然是不可能的。
严格地说,这里没有超载任何方法。这个行为在类方法的一节中被描述。@ TunIO:您的链接是关于覆盖与隐藏的关系,与重载和阴影相反,这是这里的问题。感谢您的澄清和指向java规范的正确链接!当然,只需跳过静态导入并使用Math.sqrt()
。