Подтвердить что ты не робот

Почему getClass() не доступен как статический метод?

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

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


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

Я не говорю, что вместо нестатического метода getClass() следует использовать static getClass() (такой вид - если SpecialFoo является подклассом Foo, то getClass() of 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);

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

    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
    }
}

Ответ 3

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

String.getClass()

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

Ответ 4

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

Object o = new String();
o.getClass() // returns Class<String>    
Object.class // returns Class<Object>

Ответ 5

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

Edit:

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

public class Object {

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

}

Ответ 6

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

Собственно, logger lib мог реализовать сам

static Logger logger = LoggerFactory.getLogger(); // auto detect caller class

Ответ 7

Не будет ли статический метод 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>.

Ответ 8

В дополнение к другим ответам (которые объясняют, почему мы не можем сделать статический метод с той же сигнатурой, что и нестатический метод getClass()), можно было бы задаться вопросом, можно ли, например, t20 > , так что, например, String.getStaticClass() будет эквивалентно String.class. Но, опять же, этот метод не может быть "обычным" методом. Где бы это было определено? в объекте? Затем, как бы этот единственный метод знал, что возвращать (String.class или Object.class), когда он был вызван как String.getStaticClass() или Object.getStaticClass()? Решает ли это во время выполнения? Ни за что.

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