Возможно ли получить доступ к объекту Class в статическом методе? - PullRequest
1 голос
/ 15 апреля 2010

Рассмотрим следующий класс Java:

public class Foo
{
    public static void doStuff()
    {
        // boring stuff here
    }
}

Возможно ли получить доступ к литералу класса Foo.class или только к имени класса "Foo" из статического метода, такого как doStuff()? В нестатическом методе я бы просто вызвал this.getClass(), но в статическом методе нет this для использования.


Редактировать: извините, это не было ясно - я хочу сделать это с использованием явного литерала класса Foo.class.

Ответы [ 4 ]

2 голосов
/ 15 апреля 2010

Использование Class<Foo> clazz = Foo.class


Если вам нужно что-то вроде:

class Foo {
    static Class foo(){return the current class}
}

class Bar extends Foo {

}

и ожидайте, что Bar.foo() вернет Bar при вызове Bar и Foo при вызове Foo - у вас что-то не так в вашем дизайне и, возможно, вам нужно сделать методы нестатичными.

1 голос
/ 15 апреля 2010

К сожалению, Java не дает вам хорошего способа сделать это. Вам просто нужно сослаться на Foo.class. Это то, что меня постоянно раздражает.

Для ведения журнала я решил это (идея для решения пришла из Log5j), прочитав стек, потому что это действительно раздражало пересчитывать класс для каждого регистратора каждый раз. К счастью, современные IDE делают его относительно безболезненным, так что на рефакторинг не будет оказано негативного влияния, если вам придется изменить имя класса.

РЕДАКТИРОВАТЬ: Некоторые код:

private static StackTraceElement getCallerStackTraceElement(StackTraceElement[] elements) {
    for (int i = 0; i < elements.length; i++) {
        if (elements[i].getClassName().equals(MyLogger.class.getName())) {
            return elements[i + 1];
        }
    }
    return null;
}

В данном случае MyLogger - это класс, в котором существует этот метод. Он попадает в трассировку стека и отправляется одним ранее, а затем извлекает класс из StackTraceElement.

Массив StackTraceElement [] может быть получен с помощью либо нового Exception (). GetStackTrace (), либо Thread.currentThread (). GetStackTrace (); При написании этого метода предполагается, что трассировка стека создается при первом вызове метода в MyLogger.

0 голосов
/ 15 апреля 2010

При работе со статическими методами вы можете думать о них как о библиотеках, где имя класса становится именем библиотеки. Вы указываете компилятору, какой метод bar () запускать, указав имя библиотеки (класса). Foo.bar() против Bar.bar().

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

Вы можете добавить статический метод к классу, который отвечает сам себе, в каком классе он находится:

public class Foo {

    private static class self() {
        return Foo.class;
    }

    public static void doStuff()
    {
        // Use self() to reference the Foo class
    }
}

Обратите внимание, что я сделал метод self () закрытым, потому что вне класса он не имеет смысла.

Это работает, потому что метод self () виден внутри класса и внутри статического метода.

Напротив, PHP имеет конструкцию self для ссылки на текущий класс.

0 голосов
/ 15 апреля 2010

Просто используйте Foo.class. Вам не нужно беспокоиться о наследовании или о чем-либо подобном, поскольку нет объекта, связанного со статическим методом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...