Перегрузка математики.sqrt: метод перегрузки, похоже, скрывает исходный
попытка перегрузить java.lang.Math.sqrt
статический метод для int
тип :
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.
поэтому вопросы :
- почему компилятор не может разрешить перегрузку в первом случае ?
- где это поведение указано в спецификациях языка java ?
спасибо заранее.
5 ответов
вы можете только перегружать методы в том же классе. Т. е. если вы импортируете статический метод другого класса, а затем определяете свой собственный метод с тем же именем, разрешения перегрузки не будет. Импортированная версия метода будет просто проигнорирована.
относительно того, где указано это поведение: спецификация языка определяет перегрузку такой:
Если два метода класса (оба объявлены в одном классе или оба наследуется классом или один объявленный и один унаследованный) имеют одно и то же имя, но подписи, которые не эквивалентны переопределению, тогда имя метода считается перегруженным.
обратите внимание, что в нем говорится "два метода класса". Поэтому методы, импортированные из другого класса просто не счесть.
Так как ваше определение не является перегрузкой математики.корень, его тени, его в раздел 6.3.1 определения:
объявление d из метода с именем N тени объявления любых других методов с именем n, которые находятся в охватывающей области в точке, где d происходит по всей области d.
это вполне нормально.
Написав этот код, вы не перегрузили Math.sqrt
способ в любом случае, вы просто определили Test.sqrt(int)
в качестве аргумента.
тогда возникает вопрос о вашем сообщение об ошибке.
при определении теста.метод sqrt, вы перегрузите (в этом классе) статический импорт, который вы сделали.
Итак, при вызове sqrt(1.0 * n) компилятор считает, что вы пытаетесь вызвать Test.sqrt (int) с двойным, swhich, очевидно, невозможно.
вы на самом деле не перегружены. Вещи зависают над двусмысленностью; компилятор видит return sqrt(1.0 * n);
, предполагается, что вы говорите о
да sqrt(int) in Test cannot be applied to (double)
переименуйте свою функцию с другим именем, если вы хотите вызвать Math.sqrt:
private static double mysqrt(int n)
{
return sqrt(1.0 * n);
}
в первом вызове упомянутый метод-это тот, который у вас есть return, который ожидает, что int будет его параметром, но вы отправляете ему double. так он дает ошибку компилятора.
но со вторым вызовом вы имеете в виду математику.sqrt (), который отлично работает.