Ответ 1
Просто используйте TheClassName.class
вместо getClass()
.
У меня есть класс, который должен иметь некоторые статические методы. Внутри этих статических методов мне нужно вызвать метод 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
Каков подходящий способ исправить эту ошибку времени компиляции?
Просто используйте 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()
Я сам боролся с этим. Хорошим трюком является использование текущего потока для получения 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;
}
Просто используйте литерал класса, т.е. NameOfClass.class
getClass()
метод определен в классе Object со следующей сигнатурой:
public final Класс getClass()
Так как он не определен как static
, вы не можете вызвать его в статическом блоке кода. Более подробную информацию см. В этих ответах: Q1, Q2, Q3.
Если вы находитесь в статическом контексте, вам нужно использовать выражение класса литерала для получения класса, поэтому вам в основном нужно делать:
Foo.class
Этот тип выражения называется Class Literals, и они объясняются в Java Language Specification Book следующим образом:
Литерал класса - это выражение, состоящее из имени класса, интерфейса, массива или примитивного типа, за которым следует `. ' и класс токенов. Тип литерала класса - это класс. Он оценивает объект класса для именованного типа (или для void), как определено определяющим загрузчиком класса для класса текущего экземпляра.
Вы также можете найти информацию об этой теме в документации API для класса.
Попробуйте
Thread.currentThread().getStackTrace()[1].getClassName()
или
Thread.currentThread().getStackTrace()[2].getClassName()
Попробуйте что-нибудь подобное. Меня устраивает. 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");