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 seeresolveName
The method determines the parameters passed inname
Whether or not to/
At the beginning, if not/
At the beginning, the calling class for the current method is usedcom.example.coco.Main
The package is prefixed (com/example/coco/
), and then concatenate the parameter name(definition.properties
), and finally returnscom/example/coco/definition.properties
But obviously this path doesn’t exist, so
Main.class.getResource("definition.properties") returnsnull
Copy the code
And if it is/
At the beginning,resolveName
returndefinition.properties
, continue to callClassLoader.getResource
methodsYou 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 themclasspath
The final behavior of this parameterD:\learning\demo\target\classes
This 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.Class
And it’s coming inname
Not to/
Start, so the final name isjava/lang/definition.properties
And this path doesn’t exist, so
Main.class.getClass().getResource("definition.properties") returnsnull
Copy the code
Main.class.getClass().getResource(“/definition.properties”)
Main.class.getClass
为 java.lang.Class
, the classloader of the class isnull
, i.e.,ClassLoader
forBootstrapClassLoader
As for thenull
Is eventually calledAppClassLoader.getResource
methods
ClassLoader
For more on the ClassLoader mechanism, see my other blog on the ClassLoader mechanism