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


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

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

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

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

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

8 272

8 ответов:

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

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

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

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

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

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

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

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

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

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

MethodHandles.lookup().lookupClass()

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

public static InputStream getResource(String resource) throws Exception {
   ClassLoader cl = Thread.currentThread().getContextClassLoader();
   InputStream is = cl.getResourceAsStream(resource);
   return is;
}

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

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

public final Class getClass ()

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

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

Фу.класс

этот тип выражения называется Литералы Класс и они объясняются в Java Language Specification Book следующим образом:

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

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

попробуй

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

или

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

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

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