我们在eclipse上写的.java文件最终会被编译成一个.class的字节码文件。而java源文件存储在src文件下,而编译后的.class字节码文件存储在bin文件下。
一. 通过Class.getResource方法返回的是获取文件或目录的URL
public static void test1() throws Exception, FileNotFoundException{
//本类名.class.getResource()
//参数不带任何路径文件
URL url=JDBCConnectin.class.getResource("");
//参数带一个"/"
URL url2=JDBCConnectin.class.getResource("/");
System.out.println(url); //file:/D:/java/javalianxi/javaproject/bin/yuan/JDBC/
System.out.println(url2); // file:/D:/java/javalianxi/javaproject/bin/
}
可以看出:JDBCConnectin.class.getResource("");打印的是本类所在包目录下的URL
file:/D:/java/javalianxi/javaproject/bin/yuan/JDBC/
而JDBCConnectin.class.getResource("/");打印的是字节码class根目录下的URL
file:/D:/java/javalianxi/javaproject/bin/
两者的区别不言而喻,接下来访问通过文件名访问
public static void test1() throws Exception, FileNotFoundException{
//本类名.class.getResource()
//参数不带/,代表的是该类所在的包目录下;这样可以直接访问与该类同包的文件
URL url=JDBCConnectin.class.getResource("123");
//参数带一个"/",代表的是根目录下(bin目录下);需要找到该文件的对于根目录下的具体位置,才能访问
URL url2=JDBCConnectin.class.getResource("/yuan/JDBC/123");
System.out.println(url); //file:/D:/java/javalianxi/javaproject/bin/yuan/JDBC/123
System.out.println(url2);//file:/D:/java/javalianxi/javaproject/bin/yuan/JDBC/123
}
可以看出:参数不带/,表示的是该类的所在的包目录下;这样可以直接访问与该类同包的文件
而参数带一个"/",表示的是根目录下(bin目录下);需要找到该文件的对于根目录下的具体位置,才能访问
2. 通过ClassLoader.getResource方法获取文件URL
其实就是多了一个getClassLoader(),比如JDBCConnectin.class.getClassLoader().getResource
ClassLoader.getResource方法参数同样带有一个String 类型的目录参数,但ClassLoader.getResource方法参数不支持参数为"/",因为该实例方法返回的就是类所在的根目录路径。输入带"/"开头的字符串,会返回null。参数输入不带“/”的字符串,则会返回class字节码的根目录下(bin目录下),也可以相似理解为src目录下
public static void test2() throws Exception, FileNotFoundException{
ClassLoader cl=JDBCConnectin.class.getClassLoader();
URL url=cl.getResource("");//获取的是class根目录file:/D:/java/javalianxi/javaproject/bin/
String path=url.getPath();
System.out.println(path);//D:/java/javalianxi/javaproject/bin/
URL url2=cl.getResource("/");
System.out.println(url2); //null
}
可以看出不带“/”可以获取的是class根目录下,带“/”就会打印null
public static void test() throws Exception, FileNotFoundException{
ClassLoader cl=JDBCConnectin.class.getClassLoader();
URL url=cl.getResource("yuan/JDBC/123");//获取的是class根目录:file:/D:/java/javalianxi/javaproject/bin/的url
String path=url.getPath();
BufferedReader bf=new BufferedReader(new InputStreamReader(new FileInputStream(path),"utf-8"));
int len=0;
char[] bytes=new char[1024];
while((len=bf.read(bytes))!=-1){
System.out.println(new String(bytes,0,len));
}
System.out.println(url);
System.out.println(url.toString());
}
如果把cl.getResource("yuan/usb/123")的参数换成"/yuan/usb/45"就会返回null.
最后:Class.getResource和ClassLoader.getResource的区别,就是在加载资源文件的时候,加载方式的不同,
class.getResource("/") == class.getClassLoader().getResource("")
其实,Class.getResource和ClassLoader.getResource本质上是一样的,都是使用ClassLoader.getResource加载资源的。Class.getResource真正调用ClassLoader.getResource方法之前,会先获取文件的路径(path不以'/'开头时,默认是从此类所在的包下取资源;path以'/'开头时,则是从项目的ClassPath根下获取资源)。