Java中资源加载的浅析

        Java中的资源加载总是搞不清楚。今天刻意再稍微看了一下,但是还是没有深入了解。因为要彻底搞清楚必须深刻理解ClassLoader和URL才行。现在只能写一点自己的心得。

       首先给出例子,通过例子可以帮助一些人立即解决问题。在Eclipse中我们新建如下图所示的工程。

其中:

test.properties内容为:hello=world

test2.properties内容为:hello=world2

test3.properties内容为:hello=world3

ClassLoaderTest内容如下:

package edu.xjtu.ctec.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class ClassLoaderTest {
    
public static void main(String[] args) throws IOException {
        testLoad1();
        testLoad2();
        testLoad3();
    }


    
private static void testLoad3() throws IOException {
        System.out.println(
"----test load3-----");
        String filename 
= "test3.properties";        
        InputStream input1 
= ClassLoaderTest.class.getResourceAsStream("../../../../" + filename);
        print(input1); 
        InputStream input2 
= ClassLoaderTest.class.getResourceAsStream("/" + filename);
        print(input2);        
        InputStream input3 
= ClassLoaderTest.class.getClassLoader().getResourceAsStream(filename);
        print(input3);
    }


    
private static void testLoad2() throws IOException {
        System.out.println(
"----test load2-----");
        String filename 
= "test2.properties";        
        InputStream input1 
= ClassLoaderTest.class.getResourceAsStream("config/" + filename);
        print(input1);
        InputStream input2 
= ClassLoaderTest.class.getResourceAsStream("/edu/xjtu/ctec/test/config/"
                                                   +
 filename);
        print(input2);        
        InputStream input3 
= ClassLoaderTest.class.getClassLoader().getResourceAsStream(
                                                 
"edu/xjtu/ctec/test/config/" + filename);
        print(input3);
    }


    
private static void testLoad1() throws IOException {
        System.out.println(
"----test load1-----");
        String filename 
= "test.properties";        
        InputStream input1 
= ClassLoaderTest.class.getResourceAsStream(filename);
        print(input1);
        InputStream input2 
= ClassLoaderTest.class.getResourceAsStream("/edu/xjtu/ctec/test/"
                                                    
+ filename);
        print(input2);        
        InputStream input3 
= ClassLoaderTest.class.getClassLoader()
                                                  .getResourceAsStream(
"edu/xjtu/ctec/test/" + filename);
        print(input3);
    }


    
private static void print(InputStream input) throws IOException {
        Properties properties 
= new Properties();
        properties.load(input);
        String world 
= (String) properties.get("hello");
        System.out.println(world);
    }


}
 
输出结果为:
----test load1-----
world
world
world
----test load2-----
world2
world2
world2
----test load3-----
world3
world3
world3

根据上面的结果总结如下:
Class.getResourceAsStream传入的路径可以有两种方式:
(1)不以“/”开头,则是相对与类所在的包找寻资源文件;如加载test.propertis时为:        ClassLoaderTest.class.getResourceAsStream("test.properties");
    (2)如果以“/”开头,则从当前路径开始查找,当前路径即src(当然实际上运行的时候是编译类的目的地,通常可能是您设置的bin,这里说src只是方便用户定位的,因为源代码下面的资源文件会拷贝到类所在的位置)。如加载test.properties时为

ClassLoaderTest.class.getResourceAsStream("/edu/xjtu/ctec/test/test.properties");


ClassLoader.getResourceAsStream传入的路径则统一是从当前路径开始查找的,跟Class的第二种加载方式区别在于不能以"/"开始。所以加载test.properties为
ClassLoaderTest.class.getClassLoader.getResourceAsStream("edu/xjtu/ctec/test/test.properties");

Class加载资源的时候会委托给相应的ClassLoader来加载的,不过之前会对路径进行一些处理(见下面代码中的
resolveName)。下面是Class.getResourceAsStream的源代码。
public InputStream getResourceAsStream(String name) {
        name 
= resolveName(name);
        ClassLoader cl 
= getClassLoader0();
        
if (cl==null{
            
// A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }

        
return cl.getResourceAsStream(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;
    }


而ClassLoader则委托其父类加载器在ClassPath下查找资源。具体的就没有深入 了。

 

<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值