class对象的getResource()方法、Classloader的静态方法getSystemResource()方法和实例方法getResource()方法都是从classpath路径中获取资源,如声音,图片等。但是它们的使用却有着细微的差别。
首先从它们的源码入手,下面是它们的源码:
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
public URL getResource(String name) {
URL url;
if (parent != null) {
url = parent.getResource(name);
} else {
url = getBootstrapResource(name);
}
if (url == null) {
url = findResource(name);
}
return url;
}
public static URL getSystemResource(String name) {
ClassLoader system = getSystemClassLoader();
if (system == null) {
return getBootstrapResource(name);
}
return system.getResource(name);
}
从源代码中我们可以看出,Class对象的getResource()方法和ClassLoader.getSystemResource()方法都是先去获取classloader(对于获取到的classloader为
NULL时,就会按照双亲委托模型让自己的父类加载器去查找),然后调用ClassLoader对象的getResource()方法去完成资源的查找。
但是两者使用起来毕竟是有区别的,区别就在于Class对象的getResource()方法中的 resolveName(name);对参数name的处理。
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class<?> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
看了resolveName(String)的源码,我们就能理解在JDK API中对此方法的解释了。
JDK API 1.6 Class类 写道
public URL getResource(String name)查找带有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResource(java.lang.String)。
在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:
如果 name 以 '/' ('\u002f') 开始,则绝对资源名是 '/' 后面的 name 的一部分。
否则,绝对名具有以下形式: modified_package_name/name
其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。
参数:
name - 所需资源的名称
返回:一个 URL 对象;如果找不到带有该名称的资源,则返回 null
从以下版本开始: JDK1.1
下面给出示例代码,这个示例要比对着类的组织结构来看:
Class<Test> c = Test.class;
URL url = c.getResource("test.txt");
System.out.println(url);
url = c.getResource("/my/slf4j/test/test.txt");
System.out.println(url);
url = c.getResource("/my/slf4j/test-2.txt");
System.out.println(url);
System.out.println("===============");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
url = classLoader.getResource("my/slf4j/test-2.txt");
System.out.println(url);
url = classLoader.getResource("my/slf4j/test/test.txt");
System.out.println(url);
System.out.println("===============");
url = ClassLoader.getSystemResource("my/slf4j/test-2.txt");
System.out.println(url);
url = ClassLoader.getSystemResource("my/slf4j/test/test.txt");
System.out.println(url);
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test/test.txt
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test/test.txt
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test-2.txt
===============
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test-2.txt
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test/test.txt
===============
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test-2.txt
file:/E:/workspace_JavaSE/SLF4JPractice/bin/my/slf4j/test/test.txt
说明:在开头我们讲了是通过classpath路径去获取资源文件,因此我们的资源文件(test.txt/test-2.txt)都是放在源文件这个目录下的,编译后他们会到xxx/bin/下的某个目录。即资源文件的路径是在classpath路径下。
- 大小: 7.2 KB
分享到:
相关推荐
`Class`类增加了`getResource`和`getResourceAsStream`方法的重载,可以直接通过相对路径加载资源。 9. **改进的`javac`编译器**: 编译器进行了优化,支持更多语法糖,并提升了编译速度。 10. **改进的反射API*...
JDK1.8源码分析 相关的原始码分析结果会以注解的形式体现到原始码中 ... ClassLoader#getResource Class#getResource Throwable ServiceLoader SPI 参考引用类型 ThreadLocal 线程 Proxy ClassLoader
在Linux系统中搭建一个完整的测试环境,通常包括Java开发环境(JDK)、Web服务器(Tomcat)以及数据库管理系统(MySQL)。这些组件是许多企业级应用的基础,因此掌握它们的安装和配置至关重要。以下是对这个过程的...
Java是一种广泛使用的面向对象编程语言,其英文词汇在学习和工作中非常重要。以下是一些关键的Java概念及其英文术语: 1. **Abstract Window Toolkit (AWT)**:Java的基础UI组件库,用于创建图形用户界面。 2. **...
- **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行切面逻辑。 - **基于注解的AOP**:Spring支持在方法上直接定义切面注解,如`@Before`, `@After`, `...
在这个例子中,`getClass().getResource(path)` 方法用于从 JAR 文件中获取资源。`path` 变量定义了资源的相对路径,从类路径的根目录开始。这种方法是 JDK 1.1 版本以来的标准做法,通常与 `ClassLoader` 配合使用...
- **定义**:重写方法是在子类中重新定义基类中的方法。 - **应用场景**:用于实现多态性,提供特定的实现。 #### Package 包 - **定义**:包是用于组织类的命名空间。 - **应用场景**:避免类名冲突,便于管理和...
2 利用Class实例的方法 getResource() 方法获得资源 的URL, 可以进一步打开流 如: 类 MenuFrame.class 的同包中有图片title.png URL url = getClass().getResourse("title.png") 其中"title.png" 表示相对路径...
正确的做法是使用 `getClass().getResource()` 方法获取资源文件的路径。例如: ```java ImageIcon runIcon = new ImageIcon(getClass().getResource("/images/connect.gif")); ``` 如果仍然出现错误,可以尝试将...
面向对象是一种编程范式,它将程序中的各种元素组织成对象。在Java中,几乎所有的东西都是对象。 #### 面向对象编程 (OOP: object-oriented programming) 这是一种编程方式,通过将数据和方法封装在一起形成对象来...
29. **Inheritance**:继承是面向对象编程中一个类继承另一个类的属性和方法的能力。 30. **GUI (Graphical User Interface)**:GUI是使用图形元素与用户交互的应用程序界面。 31. **JSA (Java Security ...
- **读取(Read)**:通过Session的`get()`或`load()`方法获取特定ID的对象。 ```java User user = (User) session.get(User.class, 1L); ``` - **更新(Update)**:修改对象属性后,调用`update()`方法更新...
javax.swing.ImageIcon icon = new javax.swing.ImageIcon(getClass().getResource("1.gif")); ``` 对于属性文件,Java可以自动从JAR中加载,例如: ```java ResourceBundle.getBundle("com.abc.test"); ``` ...
在标题中提到的环境是"WIN2000+JSDK+RESIN +SQL2000",这意味着我们将在Windows 2000操作系统上,使用Java Development Kit (JDK) 来编写Java代码,通过Resin应用服务器运行JSP页面,并且数据库是SQL Server 2000。...
1. **环境配置**:首先确保你已经安装了Java JDK和Maven,然后在项目中添加Spring MVC的依赖。在pom.xml文件中,你需要包含Spring Web和Spring Web MVC的相关依赖。 2. **创建MVC配置**:在Spring的配置文件(如:...
ORM允许我们将Java对象与数据库中的表进行映射,这样我们就可以通过操作对象来间接操作数据库。在Hibernate中,这个映射通常通过`hibernate.cfg.xml`配置文件和`.hbm.xml`映射文件实现。 1. **环境配置**:在开始...