2015-09-05 2 views
4

Почему возможно получить доступ к статическому методу моего суперкласса из дочернего экземпляра?Почему я могу получить доступ к статическому методу моего супер-класса из дочернего экземпляра?

public class Test { 

    public static void main(String[] args) { 
     new UtilImpl().fun(); 
     new AbstractUtil() {}.fun(); 
    } 

    static abstract class AbstractUtil { 
     public static void fun() { 
      System.out.println("Fun!"); 
     } 
    } 

    static class UtilImpl extends AbstractUtil { 
    } 

} 

Я могу согласиться с доступом к статическому методу родительского класса из экземпляра родительского класса. Но если я создаю экземпляр дочернего класса, странно иметь доступ к статическому контексту родительского класса.

PS

И каковы преимущества вызова статического метода, например?

+3

Почему? Потому что это указано именно так. Однако вы получите предупреждение. – Dici

+0

Эта тема очень хорошо освещена примерами и пояснениями здесь: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html –

+0

Вопрос на самом деле неинтересен, проверьте вопрос SO, который я связал – Dici

ответ

3

В Java разрешено вызывать статические методы с переменной экземпляра. Это определено в JLS section 8.4.3.2, включая:

Метод, объявленный как статический, называется методом класса.

Метод класса всегда вызывается без ссылки на конкретный объект.

В таком случае Java фактически отбросит экземпляр, который вы использовали, и вызовите статический метод.

Example 15.12.4.1-1 выражает это следующим образом:

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

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(); 
    } 
} 

который печатает:

Mount Monadnock 

Здесь избранное() возвращает null, но не исключено исключение NullPointerException.

+0

Это означает, что компилятор перезаписывает вызов, который будет выполняться на правом «Class' singleton right? Почему они позволяют это? – Dici

+0

Я бы лучше дал это [link] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8) – Finkelson

+0

На самом деле я знаю спецификацию.Здесь самый интересный вопрос: почему создатели Java сделали эту функцию. – Finkelson

3

Это называется наследованием. Подкласс наследует public членов родительского класса, включая методы static. Важно то, что метод static не связан ни с одним экземпляром. Вы могли бы просто сделать:

UtilImpl.fun(); 
AbstractUtil.fun(); 

Что касается компилятора, то это то же самое. Единственное различие заключается в том, что ваш код создает объекты, но они не имеют отношения к способу вызова методов (плюс, как сказал @Dici в комментариях, вы также должны получить предупреждение от компилятора).

+0

Он также вызывает статические методы из экземпляров, возможно, вы захотите что-то добавить на этом – Dici

Смежные вопросы