Java代码首先编绎成字节码,
在运行的时候再翻译成机器码。
这样在运行的时候我们就可以通过Java提供的反射方法(reflect)来得到一个Object的Class的额外信息,
灵活性很大,可以简化很多操作。
Class:
任何一个Object都能通过getClass()这个方法得到它在运行期间的Class。
得到这个Class之后可做的事情就多了,
比如动态得到它的构造函数,
成员变量,
方法等等。
还可以再生成一份新的实例,
下面只给出几个我们常用的方法,
更详细的用法参照Java
API
Ø
Class
Class.forName(String
className)
throws
ClassNotFoundException:
这是个静态方法,
通过一个Class的全称来得到这个Class。
Ø
String
getName()
取得这个Class的全称,
包括package名。
Ø
Object
newInstance()
得到一个实例,
调用缺省的构造函数。
例如我们有一个类:
com.some.util.MyClass
如果得到它的一个实例呢?
可能有以下两种方法:
MyClass
myClass
=
new
MyClass(),
直接通过操作符new生成;
或者:
MyClass
myClass
=
(MyClass)
Class.forName(“com.some.util.MyClass”).newInstance()
也许有人就会怀疑第二种方法实际意义,
能够直接new出来干嘛绕弯。
但实际上它的用处却很大,
举个例子:
用过struts的人都知道,
在action-config.xml当中定义了一系列的formBean与actionBean,
当然每个form与action都具有同类型,
这样在一个request过来的时候我可以动态的生成一个form与action的实例进行具体的操作,
但在编码的时候我并不知道具体是何种的form与action,
我只调用它们父类的方法。
你如果要用第一种方法的话,
你得在编码的时候通过一个标志来判断每一次request需要具体生成的form与action,
代码的灵活性大大降低。
总的来说在面向接口的编程当中经常使用这种方法,
比如不同数据库厂家的JDBC
Driver都是从标准的JDBC接口继承下去的,
我们在写程序的时候用不着管最终是何种的Driver,
只有在运行的时候确定。
还有XML的Parser也是,
我们使用的只是标准的接口,
最后到底是谁来实现它的,
我们用不着去管。
ClassLoader:
ClassLoader是一个抽象类,一般的系统有一个缺省的ClassLoader用来装载Class,
用ClassLoader.getSystemClassLoader()可以得到。不过有时候为了安全或有其它的特殊需要我们可以自定义自己的ClassLoader来进行loader一些我们需要的Class,
比如有的产品它用了自己的ClassLoader可以指定Class只从它指定的特定的JAR文件里面来loader,如果你想通过覆盖ClassPath方法来想让它用你的Class是行不通的。
有兴趣的可以参照Java
API
的更详细的用法说
不是这样的,通常只会有一个.
Java虚拟机启动时会调用系统类加载器Bootstrap ClassLoader去加载ExtClassLoader和ApplicationClassLoader.
ExtClassLoader:自定义的类加载器.
ApplicationClassLoader:当你用的某个类时会通过它进行加载,当然你也可以通过代码用自定义的类加载器进行class的加载.
加载是指将类加载到java虚拟机中.
看下上面的图片会发现class是Data1类中的一个静态域,这说明在Data1类的多个实例中只有一个class对象,一个对象怎么会返回多个classloader呢。classloader实在class加载到虚拟机时赋上去的.
URLClassLoader loader =new URLClassLoader(new URL[] { new URL("file:" + jarRoute) })loader.close()