Я хочу получить правильное понимание, почему ниже ошибки компиляции? В соответствии с моим пониманием Если я использую Test.xyz(), тогда компилятор ищет только статический метод, а не метод instance, то почему под компиляцией не удается?
class Test {
public static void main(String arg[]) {
Test.xyz(10); // compilation fail
}
public void xyz(int i) {
}
public static void xyz(Integer i) {
}
}
Каждый, пожалуйста, предлагайте, почему компиляция терпит неудачу, а не другие предложения и как использовать, я знаю все основные вещи Autoboxing и т.д.
Компиляция выполняется с помощью разных этапов. Извлеченные из JLS, следующие правила, которые объясняют, почему вы получили эту ошибку.
Я пропустил первый шаг, который не имеет отношения к вашему делу. Все происходит в одном классе.
Второй шаг: определение сигнатуры метода
Может быть более одного такого метода, и в этом случае выбирается наиболее конкретный. Дескриптор (тип подписи и возврата) наиболее конкретного метода используется во время выполнения, чтобы выполнить отправку метода
Первая фаза (§15.12.2.2) выполняет разрешение перегрузки без разрешения преобразования бокса или распаковки или использования вызова метода переменной arity. Если на этом этапе не обнаружен какой-либо применимый метод, обработка продолжается до второй фазы.
Из комментариев выше, метод, который вы вызываете с Test.xyz(10);
это тот, который принимает параметр int
:
public void xyz(int i) {}
Но теперь есть третий шаг: выбор подходящего метода
Если у метода invoke перед левым скобкой есть MethodName формы TypeName. Идентификатор, или если вызов метода перед левой скобкой имеет форму TypeName. Идентификатор NonWildTypeArguments, тогда объявление времени компиляции должно быть статическим или возникает ошибка времени компиляции.
Опять же, из приведенного выше комментария вы вызываете метод в static
форме,
Test.xyz(10);
но, к сожалению, метод, выбранный на втором этапе, не является статичным.
Это почему IDE, например Eclipse, предложит "изменить" xyz() "на" static ".
Но, как объяснялось в моем первом ответе (удалено), вы можете либо вызвать public void xyz(int i) {}
в экземпляре класса Test
, либо вызвать static
метод с помощью параметра Integer
: Test.xyz(Integer.valueOf(10));
,
Оба будут работать.
У вас нет типа возврата здесь:
public static xyz(Integer i) {
}
Это должно быть недействительным, если нечего возвращать:
public static void xyz(Integer i) {
}
Кроме того, вам нужно также сделать первый метод статическим:
public static void xyz(int i) {
}
Поэтому его можно вызвать из статического основного метода. Невозможно вызывать нестатические методы из статических методов. Более подробное объяснение по этому поводу: вызов нестатического метода в статическом методе в Java
void
. Нет, для того, чтобы оба метода были static
. Даже если сценарий использования немного растянут и является не очень хорошей практикой: то же имя метода с родными параметрами int и оболочки Integer ...
Итак, вот концепция autoboxing
в Java.
U писал:
Test.xyz(10); // Here 10 is a primitive int and not a java.lang.Integer object.
Но поскольку вы вызываете метод xyz
непосредственно через имя класса, явно означает, что вы хотите получить доступ к public static xyz(Integer)
методу класса Test
.
Но то, что происходит в процессе компиляции, первый ваш javac
компилятор проверяет для подписи методы, который должен быть доступен, и после этого, он проверяет для него доступ (public
, private
, protected
, по default
) и отсутствия доступа (final
, static
, etc
).
То же самое произошло с этим кодом.
Первое, что делала Java, - это проверка существования метода с сигнатурой xyz(int)
а не xyz(Integer)
вы передали в 10
а не new Integer(10)
в качестве параметра.
Он нашел два метода,
1. xyz(int)
2. xyz(Integer)
Если бы xyz(int)
не существовало, он применил бы концепцию автобоксинга (т.е. Автоматически преобразовывал 10
в new Integer(10)
) и выбрал xyz(Integer)
для выполнения. Но так как xyz(int)
существует, он не делает autobox 10
new Integer(10)
и выбирает xyz(int)
вместо xyz(Integer)
.
Теперь, поскольку ваш компилятор выбрал xyz(int)
который будет выполнен, он проверяет его модификаторы без доступа. Теперь, поскольку метод xyz(int)
нестатический, вы должны получить к нему доступ с объектом класса Test
следующим образом:
new Test().xyz(10);
И все же, если вы хотите получить доступ к static xyz(Integer)
методу static xyz(Integer)
, вам может потребоваться использовать:
Test.xyz(new Integer(10)); // You have to maunally autobox it.
Надеюсь это поможет.
static
метод. Так как он не соответствует сигнатуре xyz(int)
( xyz(10)
). Подпись вашего static
метода - xyz(Integer)
.
Вот как я сделал статический класс.
public class test {
public static void main(String arg[]) {
xyz(10);
}
public static void xyz(int i) {
}
}
Test.xyz(10);
как в вашем коде.
public static xyz(Integer i)
не имеет возвращаемого типа.