Вот пример:
extern const int b;
template
void f(int);
template
void f(long);
template
void g() {
f<0, b>(0);
}
// #1
extern const int b = 0;
int main(){
g();
}
// #2
Гипотетическое создание экземпляра в # 1 вызовет void f<0, b>(long)
, поскольку b
не является постоянным выражением в этой точке, поэтому (int)
перегружает SFINAE далеко. Создание экземпляра в # 2 (которое является точкой инстанцирования g
) вызовет void f<0, 0>(int)
, потому что к тому времени b
является постоянным выражением, перегрузка (int)
жизнеспособна и выигрывает разрешение перегрузки.
Разработайте решение в соответствии с тем, что вы хотите ...
Из класса, на который он вызван ...
получит две вещи, которыеgetResource
/ getResourceAsStream()
Итак, если вы сделаете
this.getClass().getResource("foo.txt");
, он попытается загрузить foo .txt из того же пакета, что и этот «класс», и с загрузчиком классов этого «класса». Если вы положили «/» спереди, вы абсолютно ссылаетесь на ресурс.
this.getClass().getResource("/x/y/z/foo.txt")
загрузит ресурс из загрузчика классов «this» и из пакета xyz (он должен быть в том же каталоге, что и классы в этом пакете).
Thread.currentThread().getContextClassLoader().getResource(name)
загружается загрузчиком контекстного класса, но не будет разрешать имя в соответствии с каким-либо пакетом (он должен быть абсолютно привязан)
System.class.getResource(name)
Будет загружен ресурс загрузчиком системного класса (он также должен быть абсолютно привязан, так как вы не сможете поместить что-либо в пакет java.lang (пакет System).
Просто взгляните на источник. Также указывает, что getResourceAsStream просто вызывает «openStream» по URL-адресу, возвращенному из getResource, и возвращает это.
Я ищу три места, как показано ниже. Комментарии приветствуются.
public URL getResource(String resource){
URL url ;
//Try with the Thread Context Loader.
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Let's now try with the classloader that loaded this class.
classLoader = Loader.class.getClassLoader();
if(classLoader != null){
url = classLoader.getResource(resource);
if(url != null){
return url;
}
}
//Last ditch attempt. Get the resource from the classpath.
return ClassLoader.getSystemResource(resource);
}
Ну, отчасти это зависит от того, что вы хотите, если вы действительно на самом деле в производном классе.
Например, предположим, что SuperClass
находится в A.jar и SubClass
находится в B.jar, и вы выполняете код в методе экземпляра, объявленном в SuperClass
, но где this
ссылается на экземпляр SubClass
. Если вы используете this.getClass().getResource()
, он будет выглядеть относительно SubClass
, в B.jar. Я подозреваю, что обычно не требуется.
Лично я бы чаще всего использовал Foo.class.getResourceAsStream(name)
- если вы уже знаете имя ресурса, за которым вы находитесь, и вы «Конечно, где это относительно Foo
, это самый надежный способ сделать это IMO.
Конечно, бывают случаи, когда это не , что вы хотите, тоже : судить по каждому делу по существу. Это просто «Я знаю, что этот ресурс связан с этим классом» - это самый распространенный из тех, с которыми я столкнулся.
this.getClass()
. Создайте экземпляр подкласса и вызовите метод ... он распечатает имя подкласса, а не суперкласс.
– Jon Skeet
5 October 2010 в 10:01
Я знаю, что очень поздно для другого ответа, но я просто хотел поделиться тем, что помогло мне в конце. Он также загрузит ресурсы / файлы из абсолютного пути файловой системы (а не только для пути к классу).
public class ResourceLoader {
public static URL getResource(String resource) {
final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
classLoaders.add(Thread.currentThread().getContextClassLoader());
classLoaders.add(ResourceLoader.class.getClassLoader());
for (ClassLoader classLoader : classLoaders) {
final URL url = getResourceWith(classLoader, resource);
if (url != null) {
return url;
}
}
final URL systemResource = ClassLoader.getSystemResource(resource);
if (systemResource != null) {
return systemResource;
} else {
try {
return new File(resource).toURI().toURL();
} catch (MalformedURLException e) {
return null;
}
}
}
private static URL getResourceWith(ClassLoader classLoader, String resource) {
if (classLoader != null) {
return classLoader.getResource(resource);
}
return null;
}
}
Я попробовал много способов и функций, которые были предложены выше, но они не работали в моем проекте. В любом случае я нашел решение, и вот оно:
try {
InputStream path = this.getClass().getClassLoader().getResourceAsStream("img/left-hand.png");
img = ImageIO.read(path);
} catch (IOException e) {
e.printStackTrace();
}
this.getClass().getResourceAsStream()
. Если вы посмотрите на источник метода getResourceAsStream
, вы заметите, что он делает то же самое, что и вы, но более умным способом (откат, если в классе нет ClassLoader
). Это также указывает на то, что вы можете столкнуться с потенциалом null
на getClassLoader
в вашем коде ...
– PomCompot
26 May 2017 в 07:33
this.getClass().getResourceAsStream()
не работает для меня, поэтому я использую это. Я думаю, что есть люди, которые могут столкнуться с проблемой, подобной моей.
– Vladislav
27 May 2017 в 23:03