InputStream is = getClass().getClassLoader().getResourceAsStream("helloworld.properties");中getClass()和getClassLoader()都是什么意思呀.
getClass():取得当前对象所属的Class对象
getClassLoader():取得该Class对象的类装载器
类装载器负责从Java字符文件将字符流读入内存,并构造Class类对象,在你说的问题哪里,经过它能够获得一个文件的输入流
getClass :
public final Class getClass()
Returns the runtime class of an object. That Class object is the object that is locked by static synchronized methods of the represented class.
Returns:
the object of type Class that represents the runtime class of the object.java
getClassLoader
public ClassLoader getClassLoader()
Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.
If a security manager is present, and the caller´s class loader is not null and the caller´s class loader is not the same as or an ancestor of the class loader for the class whose class loader is requested, then this method calls the security manager´s checkPermission method with a RuntimePermission("getClassLoader") permission to ensure it´s ok to access the class loader for the class.bootstrap
If this object represents a primitive type or void, null is returned.测试
Returns:
the class loader that loaded the class or interface represented by this object.
Throws:
SecurityException - if a security manager exists and its checkPermission method denies access to the class loader for the class.
See Also:
ClassLoader, SecurityManager.checkPermission(java.security.Permission), RuntimePermission
Class.getClassLoader()的一个小陷阱:)
昨天个人code总在Integer.class.getClassLoader().getResource("*********");这一句抛出空指针异常,定位为getClassLoader()返回null,查了一下jdk的文档,原来这里还有一个陷阱:
jdk中关于getClassLoader()的描述:
/**
* Returns the class loader for the class. Some implementations may use
* null to represent the bootstrap class loader. This method will return
* null in such implementations if this class was loaded by the bootstrap
* class loader.
*
* <p> If a security manager is present, and the caller's class loader is
* not null and the caller's class loader is not the same as or an ancestor of
* the class loader for the class whose class loader is requested, then
* this method calls the security manager's <code>checkPermission</code>
* method with a <code>RuntimePermission("getClassLoader")</code>
* permission to ensure it's ok to access the class loader for the class.
*
* <p>If this object
* represents a primitive type or void, null is returned.
.....this
上面的英文能够用下面的话来理解:spa
装载类的过程很是简单:查找类所在位置,并将找到的Java类的字节码装入内存,生成对应的Class对象。Java的类装载器专门用来实现这样的过程,JVM并不止有一个类装载器,事实上,若是你愿意的话,你可让JVM拥有无数个类装载器,固然这除了测试JVM外,我想不出还有其余的用途。你应该已经发现到了这样一个问题,类装载器自身也是一个类,它也须要被装载到内存中来,那么这些类装载器由谁来装载呢,总得有个根吧?没错,确实存在这样的根,它就是神龙见首不见尾的Bootstrap ClassLoader. 为何说它神龙见首不见尾呢,由于你根本没法在Java代码中抓住哪怕是它的一点点的尾巴,尽管你能时时刻刻体会到它的存在,由于java的运行环境所须要的全部类库,都由它来装载,而它自己是C++写的程序,能够独立运行,能够说是JVM的运行起点,伟大吧。在Bootstrap完成它的任务后,会生成一个AppClassLoader(实际上以前系统还会使用扩展类装载器ExtClassLoader,它用于装载Java运行环境扩展包中的类),这个类装载器才是咱们常常使用的,能够调用ClassLoader.getSystemClassLoader() 来得到,咱们假定程序中没有使用类装载器相关操做设定或者自定义新的类装载器,那么咱们编写的全部java类统统会由它来装载,值得尊敬吧。AppClassLoader查找类的区域就是耳熟能详的Classpath,也是初学者必须跨过的门槛,有没有灵光一闪的感受,咱们按照它的类查找范围给它取名为类路径类装载器。仍是先前假定的状况,当Java中出现新的类,AppClassLoader首先在类传递给它的父类类装载器,也就是Extion ClassLoader,询问它是否可以装载该类,若是能,那AppClassLoader就不干这活了,一样Extion ClassLoader在装载时,也会先问问它的父类装载器。咱们能够看出类装载器其实是一个树状的结构图,每一个类装载器有本身的父亲,类装载器在装载类时,老是先让本身的父类装载器装载(多么尊敬长辈),若是父类装载器没法装载该类时,本身就会动手装载,若是它也装载不了,那么对不起,它会大喊一声:Exception,class not found。有必要提一句,当由直接使用类路径装载器装载类失败抛出的是NoClassDefFoundException异常。若是使用自定义的类装载器loadClass方法或者ClassLoader的findSystemClass方法装载类,若是你不去刻意改变,那么抛出的是ClassNotFoundException。指针
这里jdk告诉咱们:若是一个类是经过bootstrap 载入的,那咱们经过这个类去得到classloader的话,有些jdk的实现是会返回一个null的,好比说我用 new Object().getClass().getClassLoader()的话,会返回一个null,这样的话上面的代码就会出现NullPointer异常.因此保险起见咱们最好仍是使用咱们本身写的类来获取classloader("this.getClass().getClassLoader()“),这样一来就不会有问题。code