在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java  網(wǎng)絡(luò)安全/ JAVA 類(lèi)加載器 的問(wèn)題?

JAVA 類(lèi)加載器 的問(wèn)題?

虛擬機(jī)規(guī)范規(guī)定了類(lèi)加載器的父委托機(jī)制,但是由于運(yùn)行時(shí)包(命名空間)的問(wèn)題,存在隔離,書(shū)中提到,但凡是經(jīng)過(guò)的類(lèi)加載都會(huì)保存一份class文件,但是我運(yùn)行自定義類(lèi)加載器,多次加載java.lang.String類(lèi),為什么第二次沒(méi)有在本地沒(méi)有緩存,是忘記需要重寫(xiě)那個(gè)方法嗎?

圖片描述

相關(guān)代碼

public class MyClassLoader extends ClassLoader {

  private static Path classDir = Paths.get("/Users/echo/");

  public MyClassLoader() {
    super();
  }

  @Override
  protected Class<?> findClass(String name) throws ClassNotFoundException {
    byte[] classBytes = readClassBytes(name);
    if (null == classBytes || classBytes.length == 0) {
      throw new ClassNotFoundException("can not load the class " + name + ".");
    }
    return defineClass(name, classBytes, 0, classBytes.length);
  }

  private byte[] readClassBytes(String name) throws ClassNotFoundException {
    String classPath = name.replace(".", File.separator);
    Path classFullPath = classDir.resolve(Paths.get(classPath + ".class"));
    if (!classFullPath.toFile().exists()) {
      throw new ClassNotFoundException("the class " + name + " not found.");
    }
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
      Files.copy(classFullPath, bos);
      return bos.toByteArray();
    } catch (IOException e) {
      throw new ClassNotFoundException("load the class " + name + " occur error.", e);
    }
  }

  @Override
  protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
      Class<?> c = findLoadedClass(name);
      if (c != null) {
        System.out.println("在自定義加載器緩存中找到.");
      }
      if (c == null) {
        long t0 = System.nanoTime();
        try {
          if (getParent() != null) {
            c = getParent().loadClass(name);
            if (c != null) {
              System.out.println("在父類(lèi)加載器中找到.");
            }
          } else {
            c = getSystemClassLoader().loadClass(name);
            if (c != null) {
              System.out.println("直接在根加載器中找到.");
            }
          }
        } catch (ClassNotFoundException e) {

        }
        if (c == null) {
          long t1 = System.nanoTime();
          c = findClass(name);
          if (c != null) {
            System.out.println("在自定義加載器中找到.");
          }
        }
      }
      if (resolve) {
        resolveClass(c);
      }
      return c;
    }
  }
}
    MyClassLoader classLoader = new MyClassLoader();
    classLoader.loadClass("java.lang.String");
    try {
      TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    classLoader.loadClass("java.lang.String");
回答
編輯回答
命于你

一般來(lái)說(shuō),類(lèi)只會(huì)加載一次,不需要反復(fù)加載的,所以沒(méi)有緩存一說(shuō)。而你這里手動(dòng)再加載了一次,于是會(huì)有兩次相同的輸出?!胺彩墙?jīng)過(guò)的類(lèi)加載都會(huì)保存一份class文件”這句話我覺(jué)得有問(wèn)題,應(yīng)該是加載過(guò)的類(lèi)都會(huì)產(chǎn)生一個(gè)Class對(duì)象(而不是文件),放在堆中維護(hù),而這個(gè)Class對(duì)象也不充當(dāng)緩存的角色,再加載就會(huì)被覆蓋。

2017年3月12日 19:02
編輯回答
浪蕩不羈

看你的代碼你是自己讀取并加載了類(lèi)的,這種情況需要你自己緩存已加載的類(lèi)。Java提供的幾個(gè)標(biāo)準(zhǔn)類(lèi)加載器都對(duì)經(jīng)過(guò)其加載的類(lèi)做了緩存,所以如果你把類(lèi)加載委托給這些類(lèi)加載器的話是會(huì)自動(dòng)實(shí)現(xiàn)緩存的。

2018年8月10日 02:22