java类的装载(二)
来源:优易学  2011-12-4 10:19:14   【优易学:中国教育考试门户网】   资料下载   IT书店

  在这种情况下,系统会提示我们出现异常,因为我们有两个相同的类,一个是真正的URL,一个是我在上面实现的伪类;出现异常是正常的,因为你想想,如果我们在执行一个applet的时候,程序自己实现了一个String的类覆盖了我们虚拟机上面的真正的String类,那么在这个String里面,不怀好意的人可以任意的实现一些功能;这就造成极不安全的隐患;所以java采用了一种名为“双亲委托”的加载模式;

  以下是jdk源代码:

  protected synchronized Class<?> loadClass(String name, boolean resolve)

  throws ClassNotFoundException

  {

  // First, check if the class has already been loaded

  Class c = findLoadedClass(name);

  if (c == null) {

  try {

  if (parent != null) {

  c = parent.loadClass(name, false);

  } else {

  c = findBootstrapClass0(name);

  }

  } catch (ClassNotFoundException e) {

  // If still not found, then invoke findClass in order

  // to find the class.

  c = findClass(name);

  }

  }

  if (resolve) {

  resolveClass(c);

  }

  return c;

  }

  在上面的代码中,我们可以清晰的看见,我们调用一个ClassLoader加载程序的时候,这个ClassLoader会先调用设置好的 parent ClassLoader来加载这个类,如果parent是null的话,则默认为Boot ClassLoader类,只有在parent没有找的情况下,自己才会加载,这就避免我们重写一些系统类,来破坏系统的安全;

  再来看一个明显的例子:

  package org.corey;

  public class MyCls{

  private String name;

  public MyCls(){

  }

  public MyCls(String name){

  this.name=name;

  }

  public void say(){

  System.out.println(this.name);

  }

  }

  把上面这个MyCls类打成jar包,丢进ext classLoader的加载路径;

  然后写出main类:

  package org.corey.clsloader;

  import org.corey.MyCls;

  public class TheSameClsDemo {

  /**

  * @param args

  */

  public static void main(String[] args) {

  MyCls myClsOb=new MyCls("name");

  myClsOb.say();

  System.out.println(MyCls.class.getClassLoader());

  System.out.println(System.getProperty("java.class.path"));

  System.out.println(TheSameClsDemo.class.getClassLoader());

  }

  }

  并且把MyCls类加入biild-path里面方便引用;

  结果是:

  name

  sun.misc.Launcher$ExtClassLoader@16930e2

  E:\workspace\ClassLoaderDemo\bin;E:\MyEclipse 6.0\jre\lib\ext\corey.jar

  sun.misc.Launcher$AppClassLoader@7259da

  从上面的例子可以清晰的看出ClassLoader之间的这种双亲委托加载模式;

  再来看下一个例子(摘自http://bbs.cnw.com.cn/viewthread.php?tid=95389)

  下面我们就来看一个综合的例子。首先在eclipse中建立一个简单的java应用工程,然后写一个简单的JavaBean如下:

  package classloader.test.bean;

  publicclass TestBean {

  public TestBean() {}

  }

  在现有当前工程中另外建立一测试类(ClassLoaderTest.java)内容如下:

  测试一:

  publicclass ClassLoaderTest {

  publicstaticvoid main(String[] args) {

  try {

  //查看当前系统类路径中包含的路径条目

  System.out.println(System.getProperty("java.class.path"));

  //调用加载当前类的类加载器(这里即为系统类加载器)加载TestBean

  Class typeLoaded = Class.forName("classloader.test.bean.TestBean");

[1] [2] 下一页

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训