Найти похожие ответы здесь: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html
Нарезка означает, что данные, добавленные подклассом, отбрасываются, когда объект подкласса передается или возвращается по значению или из функции, ожидающей объект базового класса.
Объяснение: Рассмотрим следующее объявление класса:
class baseclass
{
...
baseclass & operator =(const baseclass&);
baseclass(const baseclass&);
}
void function( )
{
baseclass obj1=m;
obj1=m;
}
Поскольку функции копирования в базовом классе ничего не знают о производной, только копируется только базовая часть производного. Это обычно называют срезанием.
Просто используйте TheClassName.class
вместо getClass()
.
getClass()
метод определен в классе Object со следующей сигнатурой:
public final Класс getClass ()
Поскольку он не определен как
static
, вы не можете вызвать его в статическом блоке кода. См. Эти ответы для получения дополнительной информации: Q1 , Q2 , Q3 .Если вы находитесь в статическом контексте, то вы должны использовать выражение класса литерала для получения класса, поэтому вам в основном нужно делать:
Foo.class
Этот тип выражения называется литературой класса, и они объясняются в книге спецификации языка Java следующим образом:
Литерал класса - это выражение, состоящее из имени класса, интерфейса, массива , или примитивный тип, за которым следует `. ' и класс токенов. Тип литерала класса - это класс. Он оценивает объект класса для именованного типа (или для void), как определено определяющим загрузчиком класса для класса текущего экземпляра.
Вы также можете найти информацию об этой теме на API-документация для класса.
Попробуйте
Thread.currentThread().getStackTrace()[1].getClassName()
Или
Thread.currentThread().getStackTrace()[2].getClassName()
Что касается примера кода в вопросе, стандартное решение должно явно ссылаться на класс по его имени, и даже можно обойтись без вызова getClassLoader()
:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
Этот подход все еще имеет обратную сторону, что он не очень безопасен в отношении ошибок копирования / вставки, если вам нужно скопировать этот код на ряд подобных классов.
А что касается точного вопроса в заголовке, трюк, отправленный в соседний поток :
Class currentClass = new Object() { }.getClass().getEnclosingClass();
Он использует вложенный анонимный подкласс Object
, чтобы получить контекст выполнения. Этот трюк имеет преимущество в том, что он является безопасным для копирования / вставки ...
Внимание при использовании этого в базовом классе, который наследуют другие классы:
Также стоит отметить, что если это фрагмент имеет форму статического метода некоторого базового класса, тогда значение currentClass
всегда будет ссылкой на этот базовый класс, а не на любой подкласс, который может использовать этот метод.
Class.getResource()
может вести себя несколько иначе, чем ClassLoader.getResource()
; см. stackoverflow.com/a/676273
– augurar
25 November 2015 в 20:54
Просто используйте литерал класса, то есть NameOfClass.class
Попробуйте что-нибудь подобное. Меня устраивает. 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");
В 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;
}