Как получить доступ к объекту .class в Java, не используя имя класса из статического контекста - PullRequest
0 голосов
/ 14 января 2019

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

public class Example {

    /**
     * Non static context, can only be called from an instance.
     */
    public void accessClass() {
        System.out.println(this.getClass());
    }

}

Однако в статическом контексте нет аналогичного метода, кроме только статического поля .class. Этот вопрос сосредоточен на доступе к .class из самого класса java, а не из других классов.

public class Example2 {
    //field used to demonstrate what is meant by "indirectly referencing the class name.
    private static Class<Example2> otherClass = Example2.class;
    private static int intField = 1;
   /**
     * Non static context, can only be called from an instance.
     */
     public static void accessClass() {

        // The .class static field can be accessed by using the name of the class
        System.out.println(Example2.class);

        // However the following is wrong
        // System.out.println(class);

        // Accessing static fields is in general possible
        System.out.println(intField);

        // Accessing a static field of the same Class is also possible, but does not satisfy the answer since the class name has been written in the declaration of the field and thus indirectly referenced.
        System.out.println(otherClass);

    }

}

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

Другое ограничение заключается в том, что в ответе не разрешается создавать экземпляр класса или использовать метод экземпляра .getClass().

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

Является ли это просто побочным эффектом некоторых проектных решений, или есть какая-то фундаментальная причина, по которой доступ к .class невозможен без имени класса?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Подход Java 9 с использованием StackWalker API

Class<?> currentClass = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE)
        .walk(s -> s.map(StackFrame::getDeclaringClass).findFirst().orElseThrow());

При таком подходе избегается полное использование имени класса.


Что касается причин, почему это не базовая языковая функция, я могу только догадываться, но одна вещь, которая приходит мне в голову, это некоторые сложности с вложенными классами, которые усложнят реализацию такой функции через какое-то ключевое слово. Не имеет смысла добавлять это без возможности ссылаться на несколько внешних классов из вложенного класса и т. Д.

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

0 голосов
/ 14 января 2019

Один из способов, который я нашел, - сначала получить текущую трассировку стека:

StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
StackTraceElement current = stackTrace[1];

Затем позвоните getClassName и передайте его Class.forName:

Class<?> clazz = Class.forName(current.getClassName());
...