• 对于加载器的理解 黑马程序员


    ---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
    
    
    public class Example implements IExample {
      private int counter;
      public String message() {
        return "Version 1";
      }
      public int plusPlus() {
        return counter++;
      }
      public int counter() {
        return counter;
      }
    }
    我们使用无限循环并打印出Example类信息的的main()方法。我们同样需要Example类的两个实例:example1在开始的时候创建一次,example2在每一次循环都重新创建:
    
    
    public class Main {
      private static IExample example1;
      private static IExample example2;
      
      public static void main(String[] args)  {
        example1 = ExampleFactory.newInstance();
      
        while (true) {
          example2 = ExampleFactory.newInstance();
      
          System.out.println("1) " +
            example1.message() + " = " + example1.plusPlus());
          System.out.println("2) " +
            example2.message() + " = " + example2.plusPlus());
          System.out.println();
      
          Thread.currentThread().sleep(3000);
        }
      }
    }
    IExample是一个拥有Example所有方法的接口。这是必须的,因为我们通过另外一个隔离的类加载器加载Example,所以Main不能直接使用它(否则会有ClassCastException)。
    
    
    public interface IExample {
      String message();
      int plusPlus();
    }   
    如果去掉异常处理代码,精简后的代码如下:
    
    
    public class ExampleFactory {
      public static IExample newInstance() {
        URLClassLoader tmp =
          new URLClassLoader(new URL[] {getClassPath()}) {
            public Class loadClass(String name) {
              if ("example.Example".equals(name))
                return findClass(name);
              return super.loadClass(name);
            }
          };
      
        return (IExample)
          tmp.loadClass("example.Example").newInstance();
      }
    }
    由于例子需要,方法getClassPath()可以返回一个固定的类路径(hardcoded classpath)。然而,在完整的代码中(参见后面的资源章节),你可以看到我们怎么使用ClassLoader.getResource()来做到自动适配的。
    
    现在让我们来执行Main.main,在几个循环后,我们可以看到输出:
    
    1
    2
    1) Version 1 = 3
    2) Version 1 = 0
    如我们所期望的,虽然第一个实例的counter被更新了,但第二个还是维持为”0″。如果我们修改Exampler.message()方法,使它返回”Version 2″。输出如下:
    
    1
    2
    1) Version 1 = 4
    2) Version 2 = 0    
    我们看到,第一个实例继续增加counter,但使用旧版本的类来输出版本信息。而第二个实例已经被更新,但所有的状态都已经丢失了。
    
    为了改进这个,我们尝试为第二个实例重新构造状态。我们只需从前一个迭代中复制它即可。
    
    首先我们为Example类添加一个新的copy方法(和对象的接口方法):
    
    
    public IExample copy(IExample example) {
      if (example != null)
        counter = example.counter();
      return this;
    }
    接着我们更新Main.main()方法中创建第二个对象的那行代码:
    
    1
    example2 = ExampleFactory.newInstance().copy(example2);
    等几个迭代后可以看到:
    
    1
    2
    1) Version 1 = 3
    2) Version 1 = 3
    修改Example.message()方法使它返回”Version 2″输出:
    
    1
    2
    1) Version 1 = 4
    2) Version 2 = 4
    
    ---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------
  • 相关阅读:
    C++中的指针和数组
    windows系统下JDK1.6环境变量配置
    Java Reflection (JAVA反射)
    转载:cin深入分析(下) – cin的错误处理
    OpenGL总结
    OpenGL纹理
    c/C++内存分配
    转载:cin深入分析(上) – cin输入操作处理
    c++中string的用法
    OpenGL颜色
  • 原文地址:https://www.cnblogs.com/gaopeng781/p/4334210.html
Copyright © 2020-2023  润新知