Тестовый код и результаты вывода
Структура каталогов
├── src
│ ├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── coco
│ │ ├── Main.java
│ └── resources
│ └── definition.properties
│ └── test
└── target
└── classes
├── com
└── definition.properties
Main.java
public class Main {
public static void main(String[] args) {
// 组1
System.out.println(Main.class.getResource("definition.properties"));
System.out.println(Main.class.getResource("/definition.properties"));
// 组2
System.out.println(Main.class.getClass().getResource("definition.properties"));
System.out.println(Main.class.getClass().getResource("/definition.properties"));
// 组3
System.out.println(Main.class.getClassLoader().getResource("definition.properties"));
System.out.println(Main.class.getClassLoader().getResource("/definition.properties"));
// AppClassLoader
System.out.println(Main.class.getClassLoader());
// ExtClassLoader
System.out.println(Main.class.getClassLoader().getParent());
// BootstrapClassLoader(Java中用null表示)
System.out.println(Main.class.getClassLoader().getParent().getParent());
System.out.println(Main.class.getClass().getClassLoader());
}
выход
null
file:/D:/learning/demo/target/classes/definition.properties
null
file:/D:/learning/demo/target/classes/definition.properties
file:/D:/learning/demo/target/classes/definition.properties
null
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@4f023edb
null
null
Анализ class.getResource группы 1
Исходный код Class.getResource
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
Исходный код Class.resolveName
можно увидетьresolveName
Метод будет оценивать входящие параметрыname
стоит ли/
начать, если нет/
В начале будет использоваться вызывающий класс текущего методаcom.example.coco.Main
где пакет имеет префикс (com/example/coco/
), затем соедините имя параметра (definition.properties
), и, наконец, возвращаетсяcom/example/coco/definition.properties
, но очевидно, что этот путь не существует, поэтому
Main.class.getResource("definition.properties") 返回 null
И если это/
начало,resolveName
вернутьdefinition.properties
, продолжайте звонитьClassLoader.getResource
методВидно, что правильная директория расположена/D:/learning/demo/target/classes/definition.properties
Как это позиционируется?
Main.java
ClassLoader этоAppClassLoader
, он начнется сclasspath
найти вdefinition.properties
он существует
что такое путь к классам?
Когда вы используете точку идеи для запускаMain.java
Когда , это на самом деле строка командных строк, что-то вродеjava Main
, но Idea объединяет множество параметров, как показано ниже:Скопируйте его следующим образом:
"C:\Program Files\Java\jdk1.8.0_181\bin\java.exe"
"-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3\lib\idea_rt.jar=54345:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3\bin"
-Dfile.encoding=UTF-8
-classpath
"C:\Program Files\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_181\jre\lib\deploy.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\javaws.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\jce.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfr.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\jsse.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\management-agent.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\plugin.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\resources.jar;
C:\Program Files\Java\jdk1.8.0_181\jre\lib\rt.jar;
D:\learning\demo\target\classes"
com.example.coco.Main
вclasspath
Последняя строка этого параметраD:\learning\demo\target\classes
, по сути, это скомпилированная выходная директория нашего проекта:
Группа 2 class.getClass().getResource анализ
Main.class.getClass().getResource("definition.properties")
Вы можете видеть, что фактическим вызывающим методом getResource являетсяjava.lang.Class
, а входящийname
нет/
в начале, так что окончательное имяjava/lang/definition.properties
, а этого пути не существует, поэтому
Main.class.getClass().getResource("definition.properties") 返回null
Main.class.getClass().getResource("/definition.properties")
Main.class.getClass
дляjava.lang.Class
, загрузчик класса для этого классаnull
,Прямо сейчасClassLoader
дляBootstrapClassLoader
так какnull
в конце концов позвонитAppClassLoader.getResource
метод
ClassLoader
Что касается механизма загрузки классов ClassLoader, вы можете обратиться к другому моему блогу.механизм загрузки классов