Что происходит, когда статический метод вызывается с использованием нулевой ссылки на объект?

public class CallingStaticMethod {
public static void method() {
    System.out.println("I am in method");
}
public static void main(String[] args) {
    CallingStaticMethod csm = null;
    csm.method();
   }
}

Может кто-нибудь объяснить, как статический метод вызывается в приведенном выше коде?


person java_geek    schedule 08.02.2010    source источник
comment
каждый раз, когда вы пишете такой код, котенок умирает   -  person    schedule 08.02.2010
comment
@fuzzy lollipop: :-) @OP: Много лет назад я был укушен (и сильно укушен) таким поведением по той простой причине, что мне никогда не приходило в голову вызывать метод класса, используя нотацию экземпляра. (Поэтому я думал, что вызываю метод экземпляра, и вот тут-то и начались проблемы.) Избегайте делать это любой ценой (не то чтобы я думаю, что вы говорите, что хотите; я думаю, вы не понимаете, почему это не так). не удается скомпилировать).   -  person T.J. Crowder    schedule 08.02.2010


Ответы (5)


Он был оптимизирован компилятором просто потому, что экземпляр класса не нужен. Компилятор в основном заменяет

csm.method();

by

CallingStaticMethod.method();

Как правило, это также хорошая практика, чтобы сделать это самостоятельно. Даже обычная IDE будет предупреждать о доступе к статическим методам через экземпляр, по крайней мере Eclipse делает это здесь.

person BalusC    schedule 08.02.2010
comment
Я не думаю, что это все. Вы можете вызывать статические методы, используя синтаксис экземпляра, независимо от того, можно ли его оптимизировать. Я немного удивлен, что эта конкретная формулировка работает, но я полагаю, что это имеет смысл. :-) - person T.J. Crowder; 08.02.2010
comment
он всегда может быть оптимизирован компилятором, потому что он статичен. - person Bozho; 08.02.2010
comment
Компиляторы могут оптимизировать код разными способами, чтобы он работал быстрее. Без экземпляра вам не нужно выделять/захватывать кучу и так далее. - person BalusC; 08.02.2010
comment
@Божо: Да, я полагаю, это другой взгляд на это. Я бы не стал думать об этом как об оптимизации, но это просто семантическая вещь. - person T.J. Crowder; 08.02.2010
comment
Я бы перефразировал этот ответ (но я не собираюсь его редактировать, это было бы настойчиво): я бы сказал, что вы можете использовать нотацию экземпляра для вызова методов класса, хотя это не очень хорошая идея. Как вы обнаружили, экземпляр вообще не имеет значения и может быть даже null — именно тип переменной экземпляра определяет, что представляет собой класс, и, следовательно, какой метод класса вызывается. Избегайте этого. - person T.J. Crowder; 08.02.2010
comment
Справедливо. Я немного расширил/переформулировал. - person BalusC; 08.02.2010
comment
@Т.Дж. Краудер, почему бы не дать свой собственный ответ на вопрос, в котором говорится об этом? - person Yishai; 08.02.2010

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

экземпляр.метод();

такой же как

Класс.метод();

person Dan    schedule 08.02.2010
comment
да, CallingStaticMethod.method(), чтобы использовать пример вопроса. - person b.roth; 08.02.2010
comment
Вот и все. У меня в голове по этому поводу звенел очень далекий колокольчик; Кажется, я припоминаю, что был укушен им (я никогда не использую экземпляры для вызова методов класса). - person T.J. Crowder; 08.02.2010

Спецификация языка Java говорит, что ссылка get оценивается, затем отбрасывается, а затем вызывается статический метод.
15.12.4.1. Вычислить целевую ссылку (при необходимости)

Это то же самое поведение, когда вы используете ссылку this для вызова статического метода. this оценивается, затем отбрасывается, после чего вызывается метод.

В спецификации даже есть пример, похожий на ваш пример.

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

class Test1 {
    static void mountain() {
        System.out.println("Monadnock");
    }
    static Test1 favorite(){
        System.out.print("Mount ");
        return null;
    }
    public static void main(String[] args) {
        favorite().mountain();
    }
}
person Community    schedule 23.10.2017

Ну это совершенно нормально. К статическому методу не обращается экземпляр объекта класса A. Либо вы вызываете его по имени класса, либо по ссылке, компилятор вызовет его через экземпляр класса java.lang.Class.

К вашему сведению, каждый класс (CallingStaticMethod на иллюстрации выше) в java является экземпляром класса 'java.lang.Class'. И всякий раз, когда вы определяете класс, экземпляр создается как java.lang.Class CallingStaticMethod = new java.lang.Class();

Таким образом, метод вызывается для «CallingStaticMethod», поэтому исключение нулевого указателя не произойдет.

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

person dharam    schedule 08.11.2012

Да можем. Он вызовет NullPointerException, только если мы вызываем нестатический метод с объектом null. Если метод статический, он будет запущен, а если метод нестатический, он будет выполняться через NPE...

Чтобы узнать больше, нажмите здесь...

person Sanket Dosi    schedule 09.07.2014