вы бы действительно использовали getResource()

Java

Тестовый код и результаты вывода

Структура каталогов

├── 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.javaClassLoader это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, вы можете обратиться к другому моему блогу.механизм загрузки классов