java.lang.ClassLoader 类的基本职责就是根据一个指定的类的名称,找到或者生成其对应的字节代码,然后从这些字节代码中定义出一个 Java 类,即 java.lang.ClassLoader类的一个实例。除此之外,ClassLoad 还负责加载 Java 应用所需的资源,如图像文件和配置文件等,这里我重点总结一下利用类加载器加载配置文件的几种方法。
资源配置文件:config.properties className=java.util.ArrayList
public class TestReflect {
public static void main(String[] args) throws Exception{
//一定要记住用完整的路径,但完整的路径不是硬编码,而是运算出来的。
InputStream is = new FileInputStream("config.properties");
InputStream is = TestReflect.class.getClassLoader().getResourceAsStream ("com/itcast/config.properties");
InputStream is = TestReflect.class.getResourceAsStream("resources/config.properties");
InputStream is = TestReflect.class.getResourceAsStream("/com/itcast/resources/config.properties");
Properties props = new Properties();
props.load(is);
is.close();
String className = props.getProperty("className");
Collection collections = (Collection)Class.forName(className).newInstance();
collections.add("free");
collections.add("sky");
System.out.println(collections);
}
类加载器在各种框架中普遍应用,无论是直接的加载,还是简化了加载,它们的本质都是ClassLoader。
类加载器加载的时候,当然是从classpath的根目录路径下开始寻找并加载文件;
1)我们把config.properties文件和TestReflect.java放在同一目录下时:
InputStream is = TestReflect.class.getClassLoader().getResourceAsStream("com/skysoft/config.properties");
这种方式首先找到TestReflect这个类,然后拿到该类的加载器,再由类加载器去加载资源文件。
2)config.properties文件和TestReflect.java依旧位于同一目录下:
InputStream is = TestReflect.class.getResourceAsStream("config.properties");
这种方式是类加载器的简化形式,这时是用的相对路径的形式。
3)config.properties位于com.itcast.resource包下时:
InputStream is = TestReflect.class.getResourceAsStream("resource/config.properties");
这种方式和方法二类似,也是用的对路径的形式
4)config.properties位于com.itcast.resource包下时:
InputStream is = TestReflect.class.getResourceAsStream("/com/itcast/resource/config.properties");
这种方式用的是绝对路径(简化的类加载器也可以使用绝对路径)
PS:这个例子实际上也映射出了框架的原理,因为写程序的时候无法知道要调用的类名,所以在程序里无法直接new出还没有写的类的实例,还用反射机制可以做到动态的生成对象的实例,去调用我们自己写好类中的方法,从而实现框架的功能。这也就是反射的用途所在(利用反射可以实现框架的功能)。