У меня есть класс, который должен иметь некоторые статические методы. Внутри этих статических методов мне нужно вызвать метод 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
Как правильно исправить ошибку во время компиляции?
java
static-methods
Рама
источник
источник
getResource()
до того, как будет создан экземпляр пользовательского (например, не J2SE) класса, иногда будет неудачным. Проблема в том, что JRE будет использовать загрузчик классов начальной загрузки на этом этапе, у которого не будет ресурсов приложения на пути к классам (загрузчика начальной загрузки).Ответы:
Ответ
Просто используйте
TheClassName.class
вместоgetClass()
.Объявление лесорубов
Поскольку этому уделяется так много внимания для конкретного варианта использования - чтобы обеспечить простой способ вставки объявлений журнала - я решил добавить свои мысли по этому поводу. Каркасы журналов часто ожидают, что журнал будет ограничен определенным контекстом, скажем, полным именем класса. Таким образом, они не могут быть скопированы без изменений. Предложения для вставки безопасных объявлений журнала представлены в других ответах, но у них есть недостатки, такие как раздувание байт-кода или добавление самоанализа во время выполнения. Я не рекомендую это. Копирование-вставка - это проблема редактора , поэтому решение для редактора является наиболее подходящим.
В IntelliJ я рекомендую добавить живой шаблон:
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class);
в качестве текста шаблона.className()
Теперь, если вы напечатаете,
log<tab>
он автоматически расширится доИ автоматически переформатировать и оптимизировать импорт для вас.
источник
Log
в Android, для которого требуется предоставить тег, обычно имя класса. И, возможно, есть и другие примеры. Конечно, вы можете объявить поле для этого (что является обычной практикой), но это все еще копирование и вставка.CLASS
вводаclassName()
. Это обеспечит замену $ CLASS $ на имя класса, иначе он просто будет пустым.Что касается примера кода в вопросе, стандартное решение состоит в том, чтобы явно ссылаться на класс по его имени, и даже можно обойтись без
getClassLoader()
вызова:У этого подхода есть обратная сторона: он не очень безопасен от ошибок копирования / вставки в случае, если вам нужно скопировать этот код на ряд похожих классов.
А что касается точного вопроса в заголовке, в соседней теме есть трюк :
Он использует вложенный анонимный
Object
подкласс для получения контекста выполнения. Преимущество этого трюка в том, что он защищен от копирования / вставки ...Будьте осторожны при использовании этого в Базовом классе, который наследуют другие классы:
Также стоит отметить, что если этот фрагмент сформирован как статический метод некоторого базового класса, тогда
currentClass
value всегда будет ссылкой на этот базовый класс, а не на любой подкласс, который может использовать этот метод.источник
Class.getResource()
может вести себя немного иначеClassLoader.getResource()
; см. stackoverflow.com/a/676273В Java7 + вы можете сделать это в статических методах / полях:
источник
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
Я боролся с этим сам. Хорошая хитрость заключается в использовании текущего потока для получения ClassLoader в статическом контексте. Это будет работать и в Hadoop MapReduce. Другие методы работают при локальном запуске, но возвращают нулевой InputStream при использовании в MapReduce.
источник
Просто используйте литерал класса, т.е.
NameOfClass.class
источник
getClass()
Метод определен в классе Object со следующей сигнатурой:Поскольку он не определен как
static
, вы не можете вызывать его в статическом кодовом блоке. Посмотрите эти ответы для получения дополнительной информации: Q1 , Q2 , Q3 .Если вы находитесь в статическом контексте, то вы должны использовать буквальное выражение класса, чтобы получить класс, поэтому вы должны сделать следующее:
Этот тип выражения называется литералами класса, и они объясняются в книге спецификаций языка Java следующим образом:
Вы также можете найти информацию по этому вопросу в документации API для Class.
источник
Попробуй это
Или
источник
[1]
приведет к тому, что все сообщения журнала будут сообщатьсяThread
как их источник на Android 4.4.4.[2]
похоже, дает правильный результат на Android и OpenJRE.Предположим, что есть класс Utility, тогда пример кода будет:
CustomLocation - если в ресурсах есть какая-либо структура папок, удалите этот строковый литерал.
источник
Попробуйте что-то вроде этого. Меня устраивает. Logg (Имя класса)
источник