Не можете вызвать статически импортированную перегруженную функцию, если одна с другими параметрами определена локально?

У меня есть следующий простой код Java:

A.java

import static a.A1.*;
import static a.A2.*;
class Main {
    public static int g() {return 999;}
    static {
        System.out.println("f('a'): " + f('a'));
        System.out.println("f(): " + f());
        //System.out.println("g('a'): " + g('a'));
        System.out.println("g(): " + g());
    }
}

а /A1.java

package a;
public class A1 {
    public static int f(char x) {return 1;}
    public static int g(char x) {return 123;}
}

а /A2.java

package a;
public class A2 {
    public static int f() {return 0;}
}

f определяется дважды, с перегруженными параметрами. Как вы можете видеть, импортируя оба определения f статически и называя их работает:

$ javac *.java a/*.java && java Main
f('a'): 1
f(): 0
g(): 999
Exception in thread "main" java.lang.NoSuchMethodError: main

Но когда я определил g локально, а также статически импортировать его откуда-то, это не сработало. Вот вывод, когда я раскомментирую строку 8 в Main.java:

$ javac *.java a/*.java && java Main
B.java:8: g() in Main cannot be applied to (char)
        System.out.println("g('a'): " + g('a'));
                                        ^
1 error

Зачем?

Я пытался изменить местный g на нестатический и убирающий звонок на местный g:

import static a.A1.*;
import static a.A2.*;
class Main {
    public int g() {return 999;}
    static {
        System.out.println("f('a'): " + f('a'));
        System.out.println("f(): " + f());
        System.out.println("g('a'): " + g('a'));
    }
}

Но это не сработало:

$ javac *.java a/*.java && java Main
B.java:8: g() in Main cannot be applied to (char)
        System.out.println("g('a'): " + g('a'));
                                        ^
1 error

1 ответ

Решение

Это происходит потому, что метод с именем g объявлен в вашем классе, отслеживает метод с именем g то есть statically-imported по запросу, по требованию. См. JLS §6.4.1 - Затенение:

Декларация d метода с именем n скрывает объявления любых других именованных методов n которые находятся в пределах объема в точке, где d происходит во всем объеме d,

Другие вопросы по тегам