### [编译] & [运行] 一个Java程序

1. 先把.java源代码，编译成.class字节码。
2. 执行.class字节码。

#### javac 编译

[javac] : 把源代码.java文件编译成字节码组成的.class文件。

javac命令的具体语法如下：

javac [ options ] [ sourcefiles ] [ @argfiles ]

• options: 命令行选项。比如后面要重点说的-cp,-sourcepath等。
• sourcefiles: 需要编译的.java源代码文件。一般当需要编译的文件数量不多，可以直接一个个列出来。
• @argfiles: 当需要编译文件较多，可以把.java源代码文件列在一个文本文件里。用空格空行分隔。

#### java 执行

[java] : 执行编译好的.class字节码文件。

java命令的具体语法如下：

java [ options ] class [ arguments ]

• options: 命令行选项。比如常用的-cp,-Xlint等。
• class: 编译好的.class字节码文件。一次只能执行一个.class文件。
• arguments: 传递给main函数的参数String[] args

### 虚拟机怎么找到.java源文件以及.class字节码文件？

package com.ciaoshen.test;

public class A {
public void foo() {
// do somthing
}
public static void main(String[] args) {
A a = new A();
a.foo();
}
}


.
├── bin     // .class字节码文件
│   └── com
│       └── ciaoshen
│           └── test
│               └── A.class
|
├── src     // .java源代码
|   └── com
|       └── ciaoshen
|           └── test
|               └── A.java
|
└── run.sh  // shell命令行脚本


javac -d bin src/com/ciaoshen/test/A.java

java -cp bin com.ciaoshen.test.A


#### 重点来了：Class Path

java命令想要执行A类的main方法，必须告诉虚拟机到哪里去找编译好的A.class字节码文件。这就需要非常关键的 Class Path

If -classpath and -cp are not used and CLASSPATH is not set, then the user class path consists of the current directory (.).

Linux要设置系统$CLASSPATH可以用export命令。多个$CLASSPATHLinux下可以用:分割。下面命令行表示在原先$CLASSPATH集合里新加入... export CLASSPATH=.:..:$CLASSPATH


You should arrange source files in a directory tree that reflects their package tree. For example, if you keep all your source files in \workspace, the source code for com.mysoft.mypack.MyClass should be in \workspace\com\mysoft\mypack\MyClass.java.

By default, the compiler puts each class file in the same directory as its source file. You can specify a separate destination directory with -d (see Options, below).

SEARCHING FOR TYPES

When compiling a source file, the compiler often needs information about a type whose definition did not appear in the source files given on the command line. The compiler needs type information for every class or interface used, extended, or implemented in the source file. This includes classes and interfaces not explicitly mentioned in the source file but which provide information through inheritance.
For example, when you subclass java.applet.Applet, you are also using Applet's ancestor classes: java.awt.Panel, java.awt.Container, java.awt.Component, and java.lang.Object.

When the compiler needs type information, it looks for a source file or class file which defines the type. The compiler searches for class files first in the bootstrap and extension classes, then in the user class path (which by default is the current directory). The user class path is defined by setting the CLASSPATH environment variable or by using the -classpath command line option. (For details, see Setting the Class Path).

If you set the -sourcepath option, the compiler searches the indicated path for source files; otherwise the compiler searches the user class path for both class files and source files.

You can specify different bootstrap or extension classes with the -bootclasspath and -extdirs options; see Cross-Compilation Options below.

A successful type search may produce a class file, a source file, or both. Here is how javac handles each situation:

Search produces a class file but no source file: javac uses the class file.
Search produces a source file but no class file: javac compiles the source file and uses the resulting class file.
Search produces both a source file and a class file: javac determines whether the class file is out of date. If the class file is out of date, javac recompiles the source file and uses the updated class file. Otherwise, javac just uses the class file.
javac considers a class file out of date only if it is older than the source file.

Note:   javac can silently compile source files not mentioned on the command line. Use the -verbose option to trace automatic compilation.
OPTIONS

The compiler has a set of standard options that are supported on the current development environment and will be supported in future releases. An additional set of non-standard options are specific to the current virtual machine and compiler implementations and are subject to change in the future. Non-standard options begin with -X.
Standard Options

-classpath classpath
Set the user class path, overriding the user class path in the CLASSPATH environment variable. If neither CLASSPATH or -classpath is specified, the user class path consists of the current directory. See Setting the Class Path for more details.
If the -sourcepath option is not specified, the user class path is searched for both source files and class files.

-Djava.ext.dirs=directories
Override the location of installed extensions.
-Djava.endorsed.dirs=directories
Override the location of endorsed standards path.
-d directory
Set the destination directory for class files. The destination directory must already exist; javac will not create the destination directory. If a class is part of a package, javac puts the class file in a subdirectory reflecting the package name, creating directories as needed. For example, if you specify -d c:\myclasses and the class is called com.mypackage.MyClass, then the class file is called c:\myclasses\com\mypackage\MyClass.class.
If -d is not specified, javac puts the class file in the same directory as the source file.

Note:   The directory specified by -d is not automatically added to your user class path.

-deprecation
Show a description of each use or override of a deprecated member or class. Without -deprecation, javac shows the names of source files that use or override deprecated members or classes. -deprecation is shorthand for -Xlint:deprecation.
-encoding encoding
Set the source file encoding name, such as EUC-JP and UTF-8. If -encoding is not specified, the platform default converter is used.
-g
Generate all debugging information, including local variables. By default, only line number and source file information is generated.
-g:none
Do not generate any debugging information.
-g:{keyword list}
Generate only some kinds of debugging information, specified by a comma separated list of keywords. Valid keywords are:
source
Source file debugging information
lines
Line number debugging information
vars
Local variable debugging information
-help
Print a synopsis of standard options.
-nowarn
Disable warning messages. This has the same meaning as -Xlint:none.

-source release
Specifies the version of source code accepted. The following values for release are allowed:
1.3	the compiler does not support assertions, generics, or other language features introduced after JDK 1.3.
1.4	the compiler accepts code containing assertions, which were introduced in JDK 1.4.
1.5	the compiler accepts code containing generics and other language features introduced in JDK 5. The compiler defaults to the version 5 behavior if the -source flag is not used.
5	Synonym for 1.5

-sourcepath sourcepath
Specify the source code path to search for class or interface definitions. As with the user class path, source path entries are separated by semicolons (;) and can be directories, JAR archives, or ZIP archives. If packages are used, the local path name within the directory or archive must reflect the package name.
Note:   Classes found through the classpath are subject to automatic recompilation if their sources are found.

-verbose
Verbose output. This includes information about each class loaded and each source file compiled.
-X
Display information about non-standard options and exit.


#### java

Synopsis
java [ options ] class [ arguments ]

java [ options ] -jar file.jar [ arguments ]

javaw [ options ] class [ arguments ]

javaw [ options ] -jar file.jar [ arguments ]

options
Command-line options. See Options.

class
The name of the class to be called.

file.jar
The name of the JAR file to be called. Used only with the -jar command.

arguments
The arguments passed to the main function.

Description
The java command starts a Java application. It does this by starting a Java runtime environment, loading a specified class, and calling that class's main method.

The method must be declared public and static, it must not return any value, and it must accept a String array as a parameter. The method declaration has the following form:

public static void main(String[] args)
By default, the first argument without an option is the name of the class to be called. A fully qualified class name should be used. If the -jar option is specified, then the first non-option argument is the name of a JAR file containing class and resource files for the application, with the startup class indicated by the Main-Class manifest header.

The Java runtime searches for the startup class, and other classes used, in three sets of locations: the bootstrap class path, the installed extensions, and the user class path.

Non-option arguments after the class name or JAR file name are passed to the main function.

The javaw command is identical to java, except that with javaw there is no associated console window. Use javaw when you do not want a command prompt window to appear. The javaw launcher will, however, display a dialog box with error information if a launch fails for some reason.

Options
The launcher has a set of standard options that are supported in the current runtime environment.

In addition, the default Java HotSpot VMs provide a set of non-standard options that are subject to change in future releases. See Nonstandard Options.

Standard Options
-client
Selects the Java HotSpot Client VM. A 64-bit capable JDK currently ignores this option and instead uses the Java Hotspot Server VM.

For default Java VM selection, see the Server-Class Machine Detection page at
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html

-server
Selects the Java HotSpot Server VM. On a 64-bit capable JDK, only the Java Hotspot Server VM is supported so the -server option is implicit.

For default a Java VM selection, see the Server-Class Machine Detection page at
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/server-class.html

-agentlib:libname[=options]
Loads native agent library libname, for example:

-agentlib:hprof

-agentlib:jdwp=help

-agentlib:hprof=help
See JVMTI Agent Command-Line Options at
http://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#starting

-agentpath:pathname[=options]
Loads a native agent library by full pathname.

-classpath classpath
-cp classpath
Specifies a list of directories, JAR files, and ZIP archives to search for class files. Separate class path entries with semicolons (;). Specifying -classpath or -cp overrides any setting of the CLASSPATH environment variable.

If -classpath and -cp are not used and CLASSPATH is not set, then the user class path consists of the current directory (.).

As a special convenience, a class path element that contains a base name of * is considered equivalent to specifying a list of all the files in the directory with the extension .jar or .JAR. A Java program cannot tell the difference between the two invocations.

For example, if directory mydir contains a.jar and b.JAR, then the class path element mydir/* is expanded to a A.jar:b.JAR, except that the order of jar files is unspecified. All jar files in the specified directory, even hidden ones, are included in the list. A class path entry consisting simply of * expands to a list of all the jar files in the current directory. The CLASSPATH environment variable, where defined, will be similarly expanded. Any class path wildcard expansion occurs before the Java VM is started. No Java program will ever see wild cards that are not expanded except by querying the environment. For example, by calling System.getenv("CLASSPATH").

-Dproperty=value
Sets a system property value.

If value is a string that contains spaces, then you must enclose the string in double quotation marks:

java -Dmydir="some string" SomeClass
-disableassertions[:package name"..." | :class name ]
-da[:package name"..." | :class name ]
Disable assertions. This is the default.

With no arguments, -disableassertions or -da disables assertions. With one argument ending in "...", the switch disables assertions in the specified package and any subpackages. If the argument is "...", then the switch disables assertions in the unnamed package in the current working directory. With one argument not ending in "...", the switch disables assertions in the specified class.

To run a program with assertions enabled in package com.wombat.fruitbat but disabled in class com.wombat.fruitbat.Brickbat, the following command could be used:

java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat <Main Class>
The -disableassertions and -da switches apply to all class loaders and to system classes (which do not have a class loader). There is one exception to this rule: in their no-argument form, the switches do not apply to system. This makes it easy to turn on asserts in all classes except for system classes. The -disablesystemassertions option provides a separate swith to enable assertions in all system classes.

-enableassertions[:package name"..." | :class name ]
-ea[:package name"..." | :class name ]
Enable assertions. Assertions are disabled by default.

With no arguments, -enableassertions or -ea enables assertions. With one argument ending in "...", the switch enables assertions in the specified package and any subpackages. If the argument is "...", then the switch enables assertions in the unnamed package in the current working directory. With one argument not ending in "...", the switch enables assertions in the specified class.

If a single command contains multiple instances of these switches, then they are processed in order before loading any classes. So, for example, to run a program with assertions enabled only in package com.wombat.fruitbat (and any subpackages), the following command could be used:

java -ea:com.wombat.fruitbat... <Main Class>
The -enableassertions and -ea switches apply to all class loaders and to system classes (which do not have a class loader). There is one exception to this rule: in their no-argument form, the switches do not apply to system. This makes it easy to turn on asserts in all classes except for system classes. The -enablesystemassertions option provides a separate switch to enable assertions in all system classes.

-enablesystemassertions
-esa
Enable assertions in all system classes (sets the default assertion status for system classes to true).

-disablesystemassertions
-dsa
Disables assertions in all system classes.

-help or -?
Displays usage information and exit.

-jar
Executes a program encapsulated in a JAR file. The first argument is the name of a JAR file instead of a startup class name. For this option to work, the manifest of the JAR file must contain a line in the form Main-Class: classname. Here, classname identifies the class with the public static void main(String[] args) method that serves as your application's starting point.

When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.

-javaagent:jarpath[=options]
Loads a Java programming language agent. For more information about instrumenting Java applications, see the java.lang.instrument package description in the Java API documentation at http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html

-jre-restrict-search
Includes user-private JREs in the version search.

-no-jre-restrict-search
Excludes user-private JREs in the version search.

-showversion

-splash:imagepath
Shows splash screen with image specified by imagepath.

-verbose
-verbose:class

-verbose:gc
Reports on each garbage collection event.

-verbose:jni
Reports information about use of native methods and other Java Native Interface activity.

-version

-version:release
Specifies that the version specified by the release is required by the class or JAR file specified on the command line. If the version of the java command called does not meet this specification and an appropriate implementation is found on the system, then the appropriate implementation will be used.

The release option specifies an exact version and a list of versions called a version string. A version string is an ordered list of version ranges separated by spaces. A version range is either a version-id, a version-id followed by an asterisk (*), a version-id followed by a plus sign (+), or a version range that consists of two version-ids combined using an ampersand (&). The asterisk means prefix match, the plus sign means this version or greater, and the ampersand means the logical and of the two version-ranges, for example:

-version:"1.6.0_13 1.6*&1.6.0_10+"
The meaning of the previous example is that the class or JAR file requires either version 1.6.0_13, or a version with 1.6 as a version-id prefix and that is not less than 1.6.0_10. The exact syntax and definition of version strings can be found in Appendix A of the Java Network Launching Protocol & API Specification (JSR-56).

For JAR files, the preference is to specify version requirements in the JAR file manifest rather than on the command line.

See Notes for important policy information on the use of this option.


### 参考文献

1. javac命令 - Java programming language compiler -> http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javac.html

2. java命令 - Oracle Help Center -> http://docs.oracle.com/javase/7/docs/technotes/tools/windows/java.html

3. PATH & CLASSPATH - Java Tutorials -> https://docs.oracle.com/javase/tutorial/essential/environment/paths.html

4. Setting the Class Path -> https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html#BEHJBHCD

5. Using CLASSPATH and SOURCEPATH -> http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_CLASSPATH_and_SOURCEPATH.html