как поток управления для findClass - PullRequest
3 голосов
/ 23 августа 2010

В модели родительского делегирования для загрузки классов я знаю, что loadclass () вызывается для родителя вплоть до верха иерархии загрузчика классов (при условии, что класс не загружен).В этот момент вызывается метод findClass верхнего родительского загрузчика классов.Если этот класс не найден, как управление передается методу findClass следующего загрузчика классов?

Ответы [ 2 ]

12 голосов
/ 23 августа 2010

findClass (String) будет вызываться методом loadClass (String) загрузчика классов.Реализация по умолчанию создает исключение ClassNotFoundException и предназначена для переопределения загрузчиками классов.

Метод loadClass (String) будет вызывать следующие методы в указанном порядке

  • Сначала он пытается найти, есликласс уже загружен: findLoadedClass(String)
  • Затем, если он не найден, он вызывает родительский метод classloaders loadClass(String).
  • Если не найден, он вызовет метод findClass(String) (пользовательская загрузка)

Таким образом, все, что должен сделать пользовательский загрузчик классов, это переопределить метод findClass(String) для загрузки классов пользовательским способом.Это обеспечит правильное делегирование при загрузке классов.Проверьте ссылки (javadoc), он объясняет, какие шаги предпринимаются и как findClass(String) вызывается из loadClass(String)

Так что загрузка классов происходит в следующем порядке (пример) ClassLoader A с родителем B (только объяснениеfindClass и loadClass)

               A.loadClass()
                    |
                (not-found?) (by findLoadedClass)
                    |
               B.loadClass()
                    |
                (not found?) (by findLoadedClass)
                    |
         systemclassloader.loadClass()  (Bs parent, also can be 
                    |                    called classpath classloader)
                    |
                (not found?) (by findLoadedClass)
                    |
        bootstrap classloader.loadClass() (the bootstrap classloader, 
                    |                      this has no parent)
                    |
                (not found?)
                    |
         systemclassloader.findClass()  (on system classloader, 
                    |                    will try to "find" class in "classpath")
                    |
                (not found?)
                    |
                B.findClass()
                    |
                (not found?)
                    |
                A.findClass()
                    |
                 (not found?)
                    |
            ClassNotFoundException

В любой момент времени, если класс найден (например, findClass или findLoadedClass), этот класс возвращается.

3 голосов
/ 08 ноября 2012

Вышеприведенное объяснение является всеобъемлющим и превосходным.Более простой способ понять принцип загрузки класса делегирования - прочитать исходный код.В любом случае, исходный код совсем не сложен.

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/lang/ClassLoader.java#400

400     protected Class<?> loadClass(String name, boolean resolve)
401         throws ClassNotFoundException
402     {
403         synchronized (getClassLoadingLock(name)) {
404             // First, check if the class has already been loaded
405             Class c = findLoadedClass(name);
406             if (c == null) {
407                 long t0 = System.nanoTime();
408                 try {
409                     if (parent != null) {
410                         c = parent.loadClass(name, false);
411                     } else {
412                         c = findBootstrapClassOrNull(name);
413                     }
414                 } catch (ClassNotFoundException e) {
415                     // ClassNotFoundException thrown if class not found
416                     // from the non-null parent class loader
417                 }
418 
419                 if (c == null) {
420                     // If still not found, then invoke findClass in order
421                     // to find the class.
422                     long t1 = System.nanoTime();
423                     c = findClass(name);
424 
425                     // this is the defining class loader; record the stats
426                     sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
427                     sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
428                     sun.misc.PerfCounter.getFindClasses().increment();
429                 }
430             }
431             if (resolve) {
432                 resolveClass(c);
433             }
434             return c;
435         }
436     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...