Почему getClass () не доступен как статический метод? - PullRequest
25 голосов
/ 20 апреля 2011

В статическом контексте, почему вы не можете вызвать статическую версию getClass() (вместо необходимости использовать my.package.name.MyClassName.class)?

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


ПРИМЕЧАНИЕ для ясности:

Я не говорю, что static getClass() следует использовать вместо изнестатический метод getClass() (это довольно очевидно - если SpecialFoo является подклассом Foo, то getClass() из Foo может вернуть Foo.class или SpecialFoo.class или что-то еще, и этодолжен быть определен во время выполнения).

Я говорю, что мне интересно, почему нет двух версий getClass(), одной, которая является статическим методом, который применяется только в статическом контексте, и обычнойнестатический метод getClass().Если это невозможно, то это невозможно, и это ответ.Если это возможно, но просто не было сделано, то это исторический выбор, и, возможно, есть веская причина для этого.Это то, что я хотел бы знать.

Было бы здорово объявить

final static Logger logger = LoggerFactory.getLogger(getClass());

вместо

final static Logger logger = LoggerFactory.getLogger(my.package.name.MyClass.class);

, где первое можно было бы дословно скопировать из одногокласс к следующему, тогда как последний требует, чтобы вы скопировали имя класса в каждом файле.

Ответы [ 8 ]

26 голосов
/ 10 февраля 2012

Вы можете использовать эту идиому

    Class<?> cl=new Object(){}.getClass().getEnclosingClass();

Например:

static class Bar {
    public static void main(String[] args) {
        Class<?> cl=new Object(){}.getClass().getEnclosingClass();
        System.out.println(cl==Bar.class);  //will print true
    }
}
7 голосов
/ 20 апреля 2011

Каждый объект является экземпляром класса в Java, и ни один класс не может быть экземпляром другого класса! Вот почему getClass () не является статичным, поскольку имеет смысл только в контексте объекта: вы пытаетесь найти для объекта, к какому классу он относится. Если это была статическая функция, ее можно вызывать вне объекта - но не имеет смысла писать

String.getClass()

потому что вы уже знаете, что «спрашиваете» класс String!

5 голосов
/ 20 апреля 2011

getClass () предоставляет другую функциональность, чем статический .class.Он используется для получения класса времени выполнения экземпляра, в котором он вызывается.

Object o = new String();
o.getClass() // returns Class<String>    
Object.class // returns Class<Object>
3 голосов
/ 20 апреля 2011

Если ничего другого, потому что не разрешено иметь как static, так и не static версию метода (возможно, потому что законно, если не рекомендуется, вызывать метод static в не static контекст).

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

2 голосов
/ 21 апреля 2011

Вы можете реализовать его самостоятельно.Получить трассировку стека и найти класс вызывающего

2 голосов
/ 20 апреля 2011

Поскольку, если getClass() будет статическим, его код должен быть определен в одном классе - вероятно, Object. Там вы не можете определить класс callers , и нет экземпляра объекта, который его вызывает.

Edit:

Дело не в названии; это может быть очень хорошо getClass2(). Я говорю, что если вы определяете статический метод, вы не можете знать класс, который его вызывает:

public class Object {

    public static Class<?> getClass2() {
        return ...?
    }

}
1 голос
/ 20 апреля 2011

В дополнение к другим ответам (которые объясняют, почему мы не можем создать статический метод с такой же сигнатурой, как у нестатического метода 'getClass ()'), можно задаться вопросом, возможно ли получить, скажем, static Class getStaticClass(), так что, например, String.getStaticClass() будет эквивалентно String.class. Но, опять же, этот метод не может быть «нормальным» методом. Где бы он был определен? в объекте? Тогда как этот единственный метод узнает, что возвращать (String.class или Object.class), когда он вызывается как String.getStaticClass () или Object.getStaticClass ()? Это решит это во время выполнения? Ни за что.

Статический метод не имеет смысла, потому что String.class известен (разрешен) во время компиляции. Метод не имеет смысла во время выполнения; вам нужно было бы поработать над магией компиляции, чтобы результат вызова этого метода был действительно разрешен во время компиляции.

1 голос
/ 20 апреля 2011

Не будет ли статический getClass() метод вернуть объект класса, класс, из которого состоит переменная, в которой содержится объект? Это изменит семантику getClass(). Пример:

Interface foo = new FooImpl(); 
foo.getClass(); // returns Class<FooImpl> because the runtime type is FooImpl. 
                // If getClass() was static, it would return Class<Foo>.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...