Test the code and output

The directory structure

├ ─ ─ the SRC │ ├ ─ ─ the main │ ├ ─ ─ Java │ │ └ ─ ─ com │ │ └ ─ ─ example │ │ └ ─ ─ coco │ │ ├ ─ ─ main. Java │ └ ─ ─ resources │ └ ─ ─ ├─ ├─ class.impCopy the code

Main.java

public class Main {
  public static void main(String[] args) {
    / / group 1
    System.out.println(Main.class.getResource("definition.properties"));
    System.out.println(Main.class.getResource("/definition.properties"));
    
    / / in group 2
    System.out.println(Main.class.getClass().getResource("definition.properties"));
    System.out.println(Main.class.getClass().getResource("/definition.properties"));
    
    / / group 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()); 
  }
Copy the code

The output

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
Copy the code

Group 1 class.getResource analysis

Class. GetResource source code

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);
}
Copy the code

Class. ResolveName source code

You can seeresolveNameThe method determines the parameters passed innameWhether or not to/At the beginning, if not/At the beginning, the calling class for the current method is usedcom.example.coco.MainThe package is prefixed (com/example/coco/), and then concatenate the parameter name(definition.properties), and finally returnscom/example/coco/definition.propertiesBut obviously this path doesn’t exist, so

Main.class.getResource("definition.properties") returnsnull
Copy the code

And if it is/At the beginning,resolveNamereturndefinition.properties, continue to callClassLoader.getResourcemethodsYou can see that the correct directory is located/D:/learning/demo/target/classes/definition.properties

How is that positioned?

The ClassLoader for main.java is AppClassLoader, which looks up the definition. Properties from the classpath

What is classpath?

When you run with Idea pointsMain.java“Is actually a string of command lines, similarjava Main, but Idea splices many parameters, as shown in the figure below:Copy it as follows:

"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 the jar. C: \ Program Files \ Java \ jdk1.8.0 _181 \ jre \ lib \ ext \ access - bridge - 64. The 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.MainCopy the code

Among themclasspathThe final behavior of this parameterD:\learning\demo\target\classesThis is the compiled output directory of our project:

Group 2 class.getClass().getResource analysis

Main.class.getClass().getResource(“definition.properties”)

You can see that the actual caller of the getResource method isjava.lang.ClassAnd it’s coming innameNot to/Start, so the final name isjava/lang/definition.propertiesAnd this path doesn’t exist, so

Main.class.getClass().getResource("definition.properties") returnsnull
Copy the code

Main.class.getClass().getResource(“/definition.properties”)

Main.class.getClassjava.lang.Class, the classloader of the class isnull, i.e.,ClassLoaderforBootstrapClassLoader As for thenullIs eventually calledAppClassLoader.getResourcemethods

ClassLoader

For more on the ClassLoader mechanism, see my other blog on the ClassLoader mechanism