Как вызвать getClass () из статического метода в Java? - PullRequest
316 голосов
/ 26 ноября 2011

У меня есть класс, который должен иметь несколько статических методов.Внутри этих статических методов мне нужно вызвать метод getClass (), чтобы сделать следующий вызов:

public static void startMusic() {
  URL songPath = getClass().getClassLoader().getResource("background.midi");
}

Однако Eclipse говорит мне:

Cannot make a static reference to the non-static method getClass() 
from the type Object

Как правильно исправить это?ошибка времени компиляции?

Ответы [ 8 ]

553 голосов
/ 26 ноября 2011

Просто используйте TheClassName.class вместо getClass().

105 голосов
/ 01 июля 2013

Что касается примера кода в вопросе, стандартным решением является явная ссылка на класс по его имени, и даже можно обойтись без getClassLoader() вызова:

class MyClass {
  public static void startMusic() {
    URL songPath = MyClass.class.getResource("background.midi");
  }
}

Этот подход все ещеимеет обратную сторону, что она не очень безопасна от ошибок копирования / вставки в случае, если вам нужно скопировать этот код на ряд похожих классов.

А что касается точного вопроса в заголовке, здесь есть хитростьразмещенный в смежном потоке :

Class currentClass = new Object() { }.getClass().getEnclosingClass();

Он использует вложенный анонимный подкласс Object для получения контекста выполнения.Преимущество этого трюка в том, что он защищен от копирования / вставки ...

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

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

56 голосов
/ 06 апреля 2015

В Java7 + вы можете сделать это в статических методах / полях:

MethodHandles.lookup().lookupClass()
18 голосов
/ 14 марта 2014

Я боролся с этим сам.Хорошим трюком является использование текущего потока для получения ClassLoader в статическом контексте.Это будет работать и в Hadoop MapReduce.Другие методы работают при локальном запуске, но возвращают нулевой InputStream при использовании в MapReduce.

public static InputStream getResource(String resource) throws Exception {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   InputStream is = cl.getResourceAsStream(resource);
   return is;
}
13 голосов
/ 26 ноября 2011

Просто используйте литерал класса, т.е. NameOfClass.class

9 голосов
/ 26 ноября 2011

getClass() метод определен в классе объекта со следующей сигнатурой:

открытый финальный класс getClass ()

Поскольку он не определен как static, вы не можете вызывать его в статическом кодовом блоке. См. Эти ответы для получения дополнительной информации: Q1 , Q2 , Q3 .

Если вы находитесь в статическом контексте, тогда вам нужно использовать выражение литерала класса, чтобы получить класс, поэтому вам в основном нужно сделать так:

Foo.class

Этот тип выражения называется Литералы класса , и они объяснены в Книге спецификаций языка Java следующим образом:

Литерал класса - это выражение, состоящее из имени класса, интерфейса, массива или примитивного типа, за которым следует `. ' и класс токенов. Тип литерала класса - Класс. Он оценивает объект Class для именованного типа (или для void), как это определено загрузчиком класса, определяющего класс текущего экземпляра.

Вы также можете найти информацию по этому предмету в документации API для класса.

5 голосов
/ 21 января 2016

Попробуйте

Thread.currentThread().getStackTrace()[1].getClassName()

Или

Thread.currentThread().getStackTrace()[2].getClassName()
0 голосов
/ 05 февраля 2015

Попробуйте что-нибудь подобное.Меня устраивает.Лог (Имя класса)

    String level= "";

    Properties prop = new Properties();

    InputStream in =
            Logg.class.getResourceAsStream("resources\\config");

    if (in != null) {
        prop.load(in);
    } else {
        throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
    }

    level = prop.getProperty("Level");
...