Почему статический импорт статических методов с одинаковыми именами является законным?
Предположим, что у нас есть эти пакеты и классы:
package p1;
public class A1 {
public static void a() {}
}
package p2;
public class A1 {
public static void a() {}
}
package p3;
import static p1.A1.a;
import static p2.A1.a;
public class A1 {
public static void test() {
}
}
Мне интересно, почему статический импорт методов является законным (не приведет к ошибке времени компиляции) в пакете p3
? Мы не сможем использовать их далее в методе test()
, поскольку такое использование приведет к ошибке времени компиляции.
Почему это не то же самое, что при нормальном импорте классов. Допустим, мы хотели бы импортировать классы A1
из пакетов p1
и p2
в p3
:
package p3;
import p1.A1;
import p2.A1;
такой импорт является незаконным и приведет к ошибке времени компиляции.
Ответы
Ответ 1
Неопределенность статического импорта методов может быть разрешена в точке вызова метода.
Например, если у вас был статический импорт для двух методов, которые выглядят следующим образом:
void frobnicate(int i);
// and
void frobnicate(boolean b);
Затем вы можете импортировать и использовать оба, потому что компилятор может определить, какой из них использовать, на основе аргументов, которые вы передаете (frobnicate(1)
вызывает первый, frobnicate(true)
вызывает второй).
С классами это невозможно: только Foobar a;
недостаточно, чтобы рассказать вам, какой из двух классов Foobar
вы хотите.
Также обратите внимание, что один статический импорт может импортировать несколько имен. Согласно соответствующему разделу JLS (основное внимание):
В объявлении с одним статическим импортом импортируются все доступные статические члены с заданным простым именем из типа.
Например, если два метода frobnicate
выше, где они расположены в одном классе, один импорт static
может импортировать их оба.
Ответ 2
Это потому, что вы назвали все эти классы одинаковыми. Каждый раз, когда вы вызываете этот статический метод, он ищет в самом локальном классе, который в этом случае является A1 в p3, который не содержит статический метод a(). Всегда помните, что имя класса должно быть уникальным и никогда не совпадать с другим.
Ответ 3
Я предполагаю, что не поддерживается спецификацией языка, что методы могут быть перегружены, но поля/типы не могут; поэтому java позволяет импортировать методы одного и того же имени из разных классов.
Однако два метода одной и той же сигнатуры не могут существовать в одном классе; им не следует допускать импорт.
Даже если оба метода имеют разные подписи, это все равно плохая идея. Значение имени очень важно, оно должно иметь ясность. Мы можем обрабатывать перегруженные методы из 1 класса, но "перегрузка" по всему классу является растяжкой.