Как вызвать getClass() из статического метода в Java?

У меня есть класс, который должен иметь некоторые статические методы. Внутри этих статических методов мне нужно вызвать метод 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

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

Ответ 1

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

Ответ 2

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

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

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

И что касается точного вопроса в заголовке, в смежном потоке есть трюк:

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

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

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

Ответ 3

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

MethodHandles.lookup().lookupClass()

Ответ 4

Я сам боролся с этим. Хорошим трюком является использование текущего потока для получения 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;
}

Ответ 5

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

Ответ 6

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

public final Класс getClass()

Так как он не определен как static, вы не можете вызвать его в статическом блоке кода. Более подробную информацию см. В этих ответах: Q1, Q2, Q3.

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

Foo.class

Этот тип выражения называется Class Literals, и они объясняются в Java Language Specification Book следующим образом:

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

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

Ответ 7

Попробуйте

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

или

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

Ответ 8

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

    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");