Какой метод сначала просматривается компилятором, статическим или экземпляром метода, когда используется ClassName.method ()?

1

Я хочу получить правильное понимание, почему ниже ошибки компиляции? В соответствии с моим пониманием Если я использую 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 и т.д.

  • 3
    public static xyz(Integer i) не имеет возвращаемого типа.
  • 0
    @Aditya Спасибо, я редактировал void в статической функции XYZ
Показать ещё 3 комментария
Теги:
static
compiler-errors

4 ответа

3
Лучший ответ

Почему возникает ошибка компиляции

Компиляция выполняется с помощью разных этапов. Извлеченные из 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)); ,

Оба будут работать.

  • 0
    Пожалуйста, проверьте мой отредактированный вопрос и отредактируйте свой ответ или удалите ответ на правильность, потому что это базовая вещь, которую вы дали, которую я уже знаю.
1

У вас нет типа возврата здесь:

public static xyz(Integer i) {
}

Это должно быть недействительным, если нечего возвращать:

public static void xyz(Integer i) {
}

Кроме того, вам нужно также сделать первый метод статическим:

public static void xyz(int i) {
}

Поэтому его можно вызвать из статического основного метода. Невозможно вызывать нестатические методы из статических методов. Более подробное объяснение по этому поводу: вызов нестатического метода в статическом методе в Java

  • 0
    Да для возвращаемого типа void . Нет, для того, чтобы оба метода были static . Даже если сценарий использования немного растянут и является не очень хорошей практикой: то же имя метода с родными параметрами int и оболочки Integer ...
  • 0
    @flogy пожалуйста Можете ли вы удалить свой ответ, потому что два много нежелательных ответов дали, когда я забыл поставить тип возврата под вопросом?
0

Итак, вот концепция 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.  

Надеюсь это поможет.

  • 0
    Какой метод сначала просматривается компилятором, статическим или экземпляром метода, когда используется ClassName.method ()?
  • 0
    На самом деле, он даже не смотрит на ваш static метод. Так как он не соответствует сигнатуре xyz(int) ( xyz(10) ). Подпись вашего static метода - xyz(Integer) .
0

Вот как я сделал статический класс.

public class test {
       public static void main(String arg[]) {
        xyz(10);    
        }     

        public static void xyz(int i) {
        }   
    }
  • 0
    Если вы не используете static, создайте объект класса. Затем обратитесь к Test.xyz(10); как в вашем коде.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню