A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张晴 黑马帝   /  2011-7-29 22:46  /  3028 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Test是一个类,它所在的包为dayone.test.seven, config.properties是Test类需要用到得一个配置文件,它和Test类放在同一个目录下,下面这两句是获取这个文件底层流 的两种方法
但第1种方法的路径名最前面怎么没有’/’,它们不都是绝对路径吗?这应该怎么解释呢?
(1)Test.class.getClassLoader().getResourceAsStream("dayone/test/seven/config.properties");
(2)                Test.class.getResourceAsStream("/dayone/test/seven/config.properties");

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 问得好。

查看全部评分

7 个回复

倒序浏览
黑马网友  发表于 2011-7-29 22:53:21
沙发
[code=java]public InputStream getResourceAsStream(String name)[/code]查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给[code=java]ClassLoader.getSystemResourceAsStream(java.lang.String)。 [/code]在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:

  1、如果 name 以 '/' 开始 ('\u002f'),则绝对资源名是 '/' 后面的 name 的一部分。
  2、否则,绝对名具有以下形式:
        modified_package_name/name
      其中 modified_package_name 是此对象的包名,该名用 '/' 取代了 '.' ('\u002e')。

评分

参与人数 1技术分 +1 收起 理由
老罗 + 1 你的答案楼下不满意,哈哈。

查看全部评分

回复 使用道具 举报
黑马网友  发表于 2011-7-29 23:00:27
藤椅
有点看不懂, 能不能再说通俗点 ?
回复 使用道具 举报
黑马网友  发表于 2011-7-30 15:07:24
板凳
有没有哪位高手能给补充一下??
回复 使用道具 举报
黑马网友  发表于 2011-7-30 15:11:25
报纸

回复 板凳 的帖子

春春会伤心的。
回复 使用道具 举报
黑马网友  发表于 2011-7-30 15:44:15
地板
好问题,不过敢问楼主"第一种"是哪一种??
回复 使用道具 举报
诶,丢人了,代码又能看见了…神奇的手机

getResourceAsStream方法在ClassLoader中将传进来的String变成了URL类:
public InputStream getResourceAsStream(String name){
URL url = getResource(name);
……
}
而在Class类中的方法原代码却是这样写的:
name = resolveName(name); 然后才会传给一个ClassLoader对象
在这个方法中会去掉第一位的'/' 
回复 使用道具 举报
詹季春 黑马帝 2011-7-30 18:46:25
8#
要区分Class的getResourceAsStream和ClassLoader的getResourceAsStream方法。
ClassLoader的该方法如果name以/开头那么就什么也找不到了。

Class的getResourceAsStream方法
1、如果name以/开头那么就把/以后的name传递给ClassLoader的 getResourceAsStream方法。
2、如果不已/开头那么将该class的包名加上name作为参数(用/代替.)之后 传给ClassLoader的对应方法。[code=java]package   cn.itcast.heima;
import   java.io.*;

......
InputStream   in   =   test.getClass().getResourceAsStream( "heima.txt ");
InputStream   in   =   test.getClass().getResourceAsStream( "/cn/itcast/heima/heima.txt ");  
InputStream   in   =   ClassLoader.getSystemClassLoader().getResourceAsStream( "cn/itcast/heima/heima.txt ");
....... [/code]从上可以看出前一个只是引用了后一个的方法。不过其中加了一些判断。
我们可以看下源代码就了解到:[code=java]    // java.lang.Class
    public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) { // 如果找不到ClassLoader,就寻找系统资源
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name); // 否则就调用ClassLoader对应方法
    }
//...
    /**
     * Add a package name prefix if the name is not absolute Remove leading "/"
     * if name is absolute
     */
    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;
    }[/code]两个方法的区别是资源的定义不同:
一个主要用于相对与一个object取资源,而另一个用于取相对于classpath的资源,用的是绝对路径。
由此可见,如果使用Class.getResourceAsStream(String)方法,则资源名要么设置为类所在包的相对名,要么设置为全路径名,而如果使用ClassLoader的相应方法,则要设置为不带根的全路径名。也就是楼主所说的不加"/"
[ 本帖最后由 詹季春 于 2011-07-30  19:12 编辑 ]

评分

参与人数 1技术分 +1 收起 理由
admin + 1 这样大家应该会满意了!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马