Перегрузка математики.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.

поэтому вопросы :

  1. почему компилятор не может разрешить перегрузку в первом случае ?
  2. где это поведение указано в спецификациях языка 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 (), который отлично работает.