Do you really understand the configuration of the Java environment variables?

Source: Internet
Author: User

first, let's take a look at what the system does when we execute Javac and java with commands, and if we now have a folder like 1 , there are two Java files.

Figure 1: File directory

among them, the content of Main.java is very simple:

public class main{public static void Main (string[] args) {System.out.println ("Hello World"); }}

We first switch directories under CMD to the directory G:\oj\workdir\kown\test shown in 1:

Figure 2: Switching directories

Find a fun thing, in the user (home) directory directly switch, it is not possible, must have changed the disk character command to switch,2, you can exchange the first sentence and the second sentence order. Of course, the quicker way is to press F4 in the folder shown in Figure 1, type cmd and enter.

let's compile a little bit. Main.java file input javac Main.java

Figure 3:javac Main

cmd How to do javac Main.java C c++ Main function int main (int argc, char *argv[]) argc is the number of parameters, argv[] javac c Main function, our external program can pass the external parameter to the font-family by argv[] cmd

So the whole process is that we are in cmd Enter javac main.java javac main.java As a parameter passed to cmd argc Cmd parse parameter string, know to execute javac program, CMD first find out if there is no javac javac.com, Javac.bat or javac.exe javac main.java Try it, you know cmd The first thing to look for is the current directory.

if found then executes, if not found, start looking for the system environment variable directory specified by path. That's why we 're adding directories like C:\Program files\java\jdk7\bin to the system environment variable path .

now let's execute the Java command, first take a look at our directory situation, just one more compiled Main.java generated bytecode file main.class:

Figure 4: Current directory

Execute Java Main

Figure 5:java Main

so What are the similarities and differences between executing Java and javac? For the CMD process is the same, just execute javac and Java The two programs themselvesare different, javac just compile java source code becomes The byte code of the class. Java is the execution byte code. Let's take a look at the Java implementation process.

first, look through path to Java.exe, which is the executable file under Windows, in C:\Program files\java\jdk7\ can be found under bin.

java.exe connects a Jvm.dll dll file is Windows dynamic link library, which is a number of modules, functions, but he can dynamically load only. The function of jvm.dll jvm ( Java virtual machine),

Then, jvm initialize a bootstraploader (startup ClassLoader) instance, Bootstrap Loader Auto load Extendedloader (Standard extension class loader) and its parent loader set to Bootstrap loader Bootstrap loader auto load appclass loader (System ClassLoader), and its parent loader set to Extended loader

with the ClassLoader, you need to load the class. The first is the Bootstrap Loader load,the path of the Bootstrap Loader load class is written in the JRE environment variable,the JVM Run is also added to the system environment variable, Can be obtained by means of System.getproperty ("Sun.boot.class.path") . Similarly , the directory of Extended Loader loaded classes can be obtained through System.getproperty ("Java.ext.dirs") . The directory of the Appclassloader load class can be obtained by System.getproperty ("Java.class.path") .

See Appclassloader 's Java.class.path is not a bit familiar, this is the Java system environment variable classpath.

when you run a class, the specified class is always loaded by the Appclass Loader(System ClassLoader). However, each classloader will first delegate the load task to its parent loader, if the parent cannot find it and then load it by itself.

So when we run Java Main, Appclassloader will look for Main.class in the Bootstraploader specified load path. The Main.class is then found in the path specified by Extendedloader and finally in the Classpath directory specified by appclassloader .

It is important to note that there are two possible reasons why Java Main can be loaded into main.class when we run it in the current directory :

One is: appclassloader searched for the current path.

the second is: The JVM dynamically adds the current path to the classpath .

by putting the current folder under the Openmain.class file added to classpath , just let their output is different, after testing found that the first execution is classpath under the same name file, we know it should be the JVM Dynamically adds the current path to the classpath last.

we notice that Main.java is not a package name, then what to do with the package name inside? Let's have a look at Openmain.java.

the Openmain.java class capacity is as follows:

Package Kown.test;public class openmain{public static void Main (string[] args) {System.out.         println ("Hi World"); }}

compiling Openmain.java:

Figure 6:javac-encoding

we find that encoding is not a mapping error, this is a coding problem,javac default character set used by the system environment variable (Chinese is generally GBK), because the Openmain.java file above is used utf-8 encoding. So no problem we can use:javac–encoding utf-8 Openmain.java to compile, you can also save the Openmain.java as ANSI format, and then to compile, The above is handled using the code that changed the file Openmain.java .

running:java openmain

Figure 7:wrong name

discover wrong Name:/kown/test/openmain, what's going on here? Let's take a look at the difference between Figure 7 above and figure 8 below .

Figure 8: Unable to load main class

Figure 8 The cause of this error is that Bootstraploader,extendedloader and Appclassloader are not found at all in the loaded directory Openmain.class this file. The reason for the error in Figure 7 is that the Openmain.class file was found , but the Openmain class was not found . Let's analyze the error inthe 7, Exception in Thread main java.lang.NoClassDefFoundError:OpenMain ... Through this we know that the JVM has started and that the Openmain.class bytecode has been loaded . But it gave us a wrong name :kown/test/openmain

we know that kown/test is our package name and added the package name to create the error.

Rethinking Why Java introduces the concept of a package in the same way that namespaces are meant to differentiate between different modules with the same name, think about why we can use the same class name in different packages. That's because we put the name of the class in front of the class name, because the registration is different, so the name of our class is actually different. This is why in Java we often have to use full-limit names such as we use the Class.forName (java.lang.String) We want the full class name java.lang.String The reason.

We're looking at the following figure 9 and figure two graphs to continue the analysis :

Figure 9: running in the same directory as the Openmain.class

Figure : Run under the parent directory of the package name

Scenario One: Figure 9: The directory where the Openmain.class is located G:\oj\workdir\kown\test the Java openmain and Java Kown/test/openmain, one is with the package name, one is not with the package name. When we do not add the name of the time to tell us the class name error, when I add the name of the package tells us that the class is not found.

Scenario Two: Figure : The parent directory of the package name G:\oj\workdir the Java openmain and java kown/test/openmain, respectively , Is also a bag with the name, one is not with the package name, when we do not add the name of the time to tell us that the class is not found, add the package name finally run successfully.

Why so magical, let's analyze and summarize:

Combining situation one and case two, we can boldly guess Java first of all through his parameters to find class Java openmain Because the current directory has Openmain.class file, so load class file stage no problem, then load class, java parameters Openmain As the class name, with a similar Class.forName ("Openmain"); this way to load the Openmain Java.lang.NoClassDefFoundError:OpenMain Unknown source error, because there is no openmain Kown.test.openmain this class.

for scenario two, the direct Java openmain error should actually not be found in the main class, because G:\oj\workdir does not have this class at all, the reason is like the above situation, because I want to test appclassloader searched for the current path, or the JVM dynamically added the current path to the classpath . Put Openmain into the jar package and added the C:\Program files\java\jre7\lib\ext folder. Must be a jar package, not a class file to be valid.

so Java will search the class file by the path specified by the parameter , then load the class file into memory, and then add the path with the file name as the fully-restricted class name to load the classes.


Do you really understand the configuration of the Java environment variables?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.