Подтвердить что ты не робот

Почему статический импорт статических методов с одинаковыми именами является законным?

Предположим, что у нас есть эти пакеты и классы:

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;

такой импорт является незаконным и приведет к ошибке времени компиляции.

4b9b3361

Ответ 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 класса, но "перегрузка" по всему классу является растяжкой.