Difference between revisions of "Compiling and Launching"
From Suhrid.net Wiki
Jump to navigationJump to search (→java) |
|||
(11 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
* if the directory does not exist, there will be an error. | * if the directory does not exist, there will be an error. | ||
* the directories for the package structure will however be automatically created by javac. | * the directories for the package structure will however be automatically created by javac. | ||
+ | * javac does not need to be invoked in a package-aware manner for compiling classes (unlike java) | ||
+ | * So a source file need not reside in a package specific location, unlike a .class file. | ||
+ | * For e.g. if there is a net.suhrid.SomeClass - SomeClass.java can be located in any directory not mandatory to have a net/suhrid directory hierarhcy. | ||
+ | * javac can also be invoked from any directory to compile a file. Of course it will generate the appropriate directories as per the package name for the .class file - because it matters. | ||
There are four things to keep in mind while compiling: | There are four things to keep in mind while compiling: | ||
Line 26: | Line 30: | ||
* -classpath and -cp can be either of the arguments to instruct the compiler to look for classes used by the compiled file. | * -classpath and -cp can be either of the arguments to instruct the compiler to look for classes used by the compiled file. | ||
* Typically used for pre-compiled third party classes/libraries. | * Typically used for pre-compiled third party classes/libraries. | ||
− | * In case of directories, the directory which contains the hierarchy of the package structure of the class files. (similar to sourcepath) | + | * In case of directories, the directory which contains the hierarchy of the package structure of the class files. (similar to sourcepath). This is quirky and very important: |
+ | |||
+ | Assume this directory structure: | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | somedir | ||
+ | | | ||
+ | foo | ||
+ | | | ||
+ | bar | ||
+ | | -- A.class | ||
+ | | -- B.java | ||
+ | |||
+ | and the declarations: | ||
+ | |||
+ | package bar; | ||
+ | public class A; | ||
+ | |||
+ | package bar; | ||
+ | public class B; | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | * When in bar directory, '''''javac B.java will not work !''''' even with the classpath pointing to the current directory. | ||
+ | * Why ? the classpath has to be the location containing the hierarchy of the package structure starting from bar (i.e. foo). | ||
+ | |||
+ | To compile B we can: | ||
+ | # change to foo directory and then use: javac bar/B.java (since default classpath points to . no need to use -classpath) | ||
+ | # from testdir : javac -classpath foo foo/bar/B.java | ||
+ | |||
* In case of jar files, the argument is the location of the jar file - '''including the jar file name'''. Here the jar file acts as the directory which contains the hierarchy of the package structure of the third party class files. | * In case of jar files, the argument is the location of the jar file - '''including the jar file name'''. Here the jar file acts as the directory which contains the hierarchy of the package structure of the third party class files. | ||
Line 36: | Line 70: | ||
* Exactly 1 class must be specified which has the main() method. | * Exactly 1 class must be specified which has the main() method. | ||
* This class name has to be the fully qualified class name. | * This class name has to be the fully qualified class name. | ||
+ | * If the directory containing top level package is present from where java is being executed, then cp is not mandatory. | ||
+ | * However if cp is specified, the current directory is NOT included by default, it has to be made explicit. | ||
* java [options] class-name [cmd-line arguments to the class] | * java [options] class-name [cmd-line arguments to the class] | ||
Line 42: | Line 78: | ||
* If no args are passed, String[] args will be a zero-length array - it won't be null. | * If no args are passed, String[] args will be a zero-length array - it won't be null. | ||
* The first-argument is args[0] and the fourth will be args[3] | * The first-argument is args[0] and the fourth will be args[3] | ||
+ | * Anything in the command-line after the class-name is treated as an argument, space separated string should be double quoted | ||
+ | ** java net.suhrid.ClassA -ea -cp (-ea,-cp are treated as arguments and not as switches) | ||
+ | ** java net.suhrid.ClassA "Hello World" (Hello World is a single argument string) | ||
+ | |||
+ | * IMPORTANT : If a class does not have a main() method and is launched from the command-line, a NoSuchMethodError will be thrown! | ||
+ | * However, since the class is loaded, all the static init blocks will be executed ! | ||
+ | * For the below class, with the invocation: java init.Init3, the following is the output: | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | java init.Init3 | ||
+ | [1, 2, 3] | ||
+ | Exception in thread "main" java.lang.NoSuchMethodError: main | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | <syntaxhighlight lang="java5"> | ||
+ | |||
+ | package init; | ||
+ | |||
+ | import java.util.Arrays; | ||
+ | |||
+ | public class Init3 { | ||
+ | |||
+ | static int[] ia = {1,2,3}; | ||
+ | |||
+ | static { | ||
+ | System.out.println(Arrays.toString(ia)); | ||
+ | } | ||
+ | |||
+ | { | ||
+ | int x = 10; | ||
+ | System.out.println("Inited x to 10"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
options | options | ||
Line 56: | Line 127: | ||
* If no classpath is specified, the current directory (from which java is executed) is searched. If a classpath is specified, the current directory (if required) needs to be added explicitly to the classpath. | * If no classpath is specified, the current directory (from which java is executed) is searched. If a classpath is specified, the current directory (if required) needs to be added explicitly to the classpath. | ||
* As soon as a class is found, jvm will stop searching for that class. So order of specifying is important. | * As soon as a class is found, jvm will stop searching for that class. So order of specifying is important. | ||
+ | |||
+ | |||
+ | * '''Note: javac will compile a file even it is not located in the directory structure corresponding to its package.''' | ||
+ | * '''java however expects the file to be located in the directory appropriate package.''' | ||
== jar == | == jar == | ||
Line 68: | Line 143: | ||
* This does not extend to subpackages! for e.g it won't apply to java.util.regex. Import only applies to a single package. | * This does not extend to subpackages! for e.g it won't apply to java.util.regex. Import only applies to a single package. | ||
* ambiguous imports and static imports (like using the same classname twice from different packages) will cause compiler errors. | * ambiguous imports and static imports (like using the same classname twice from different packages) will cause compiler errors. | ||
+ | * To import inner classes, we can specify the name or a wildcard after the outer class name e.g. import java.util.Map.*; | ||
− | Static imports | + | === Static imports === |
* Used to alias a class's static members (field's and methods) | * Used to alias a class's static members (field's and methods) | ||
* Has to be "import static" only | * Has to be "import static" only | ||
+ | * Can only be used to import a classes fields. '''Static import of only a CLASS IS ILLEGAL.''' | ||
+ | * Enum constants can be static imported so that they can be used without type name. | ||
* wildcards can be used | * wildcards can be used | ||
* e.g. | * e.g. | ||
Line 80: | Line 158: | ||
import static java.lang.Thread.MAX_PRIORITY; | import static java.lang.Thread.MAX_PRIORITY; | ||
import static java.util.Collections.*; | import static java.util.Collections.*; | ||
+ | //import static java.lang.System; //ILLEGAL | ||
public class SITest { | public class SITest { |
Latest revision as of 10:03, 13 September 2011
Contents
javac
- javac by default places the generated class files in the same directory as the source files.
- use the javac -d option to place the class files in some other directory.
- if the directory does not exist, there will be an error.
- the directories for the package structure will however be automatically created by javac.
- javac does not need to be invoked in a package-aware manner for compiling classes (unlike java)
- So a source file need not reside in a package specific location, unlike a .class file.
- For e.g. if there is a net.suhrid.SomeClass - SomeClass.java can be located in any directory not mandatory to have a net/suhrid directory hierarhcy.
- javac can also be invoked from any directory to compile a file. Of course it will generate the appropriate directories as per the package name for the .class file - because it matters.
There are four things to keep in mind while compiling:
- Which are the files that need to be compiled ?
- The directory where javac looks for other .java source files that are used by the file to be compiled.
- The directory where javac looks for class files that are used by the file to be compiled.
- The directory to place the generated class files in.
Options:
- the -sourcepath is the directory where the compiler looks for other java files.
- It has to be the directory that contains the hierarchy of the package structure of the source files.
for e.g. if we are compiling ClassB.java in directory src/net/suhrid/pkgB/ClassB.java which uses ClassA located in net/suhrid/pkgA/pkgA/ClassA.java then argument to sourcepath must be the "src" directory: javac -sourcepath src net/suhrid/pkgB/ClassB.java
- this option will also compile the files which are referenced by the file being compiled.
- -classpath and -cp can be either of the arguments to instruct the compiler to look for classes used by the compiled file.
- Typically used for pre-compiled third party classes/libraries.
- In case of directories, the directory which contains the hierarchy of the package structure of the class files. (similar to sourcepath). This is quirky and very important:
Assume this directory structure:
somedir
|
foo
|
bar
| -- A.class
| -- B.java
and the declarations:
package bar;
public class A;
package bar;
public class B;
- When in bar directory, javac B.java will not work ! even with the classpath pointing to the current directory.
- Why ? the classpath has to be the location containing the hierarchy of the package structure starting from bar (i.e. foo).
To compile B we can:
- change to foo directory and then use: javac bar/B.java (since default classpath points to . no need to use -classpath)
- from testdir : javac -classpath foo foo/bar/B.java
- In case of jar files, the argument is the location of the jar file - including the jar file name. Here the jar file acts as the directory which contains the hierarchy of the package structure of the third party class files.
- Note multiple directories can be specified in the -sourcepath and the -classpath options (separated by ":" in unix and ";" in Windows). Typically the sourcepath will be a single directory whereas the classpath will have multiples directories or jar files for various third party libraries.
java
- Launches the JVM.
- Exactly 1 class must be specified which has the main() method.
- This class name has to be the fully qualified class name.
- If the directory containing top level package is present from where java is being executed, then cp is not mandatory.
- However if cp is specified, the current directory is NOT included by default, it has to be made explicit.
- java [options] class-name [cmd-line arguments to the class]
cmd-line arguments
- args are space separated.
- If no args are passed, String[] args will be a zero-length array - it won't be null.
- The first-argument is args[0] and the fourth will be args[3]
- Anything in the command-line after the class-name is treated as an argument, space separated string should be double quoted
- java net.suhrid.ClassA -ea -cp (-ea,-cp are treated as arguments and not as switches)
- java net.suhrid.ClassA "Hello World" (Hello World is a single argument string)
- IMPORTANT : If a class does not have a main() method and is launched from the command-line, a NoSuchMethodError will be thrown!
- However, since the class is loaded, all the static init blocks will be executed !
- For the below class, with the invocation: java init.Init3, the following is the output:
java init.Init3
[1, 2, 3]
Exception in thread "main" java.lang.NoSuchMethodError: main
package init;
import java.util.Arrays;
public class Init3 {
static int[] ia = {1,2,3};
static {
System.out.println(Arrays.toString(ia));
}
{
int x = 10;
System.out.println("Inited x to 10");
}
}
options
- -D is used to pass properties to the JVM which can be retrieved using System.getProperties().
- e.g. java -Dname=suhrid someclass
- There is no space between -D and the name=value pair!
- -cp / -classpath : same as in javac.
- Order of loading classes
- Bootstrap classes : Core classes
- Extensions in jre/lib/ext
- Defined classpath either through OS env variable or command line. Cmdline ovverrides OS classpath.
- If no classpath is specified, the current directory (from which java is executed) is searched. If a classpath is specified, the current directory (if required) needs to be added explicitly to the classpath.
- As soon as a class is found, jvm will stop searching for that class. So order of specifying is important.
- Note: javac will compile a file even it is not located in the directory structure corresponding to its package.
- java however expects the file to be located in the directory appropriate package.
jar
- jar -cf <jartobecreated.jar> <dirname1-withclasses> <dirname2-withclasses>
- jar is recursive when adding directories
imports
- import is only an alias for a qualified class name. It's only purpose is to save typing and make code more readable.
- import java.util.* will allow us to use HashMap without saying java.util.HashMap everytime
- import java.util.* says use short name for all classes in java.util package ONLY.
- This does not extend to subpackages! for e.g it won't apply to java.util.regex. Import only applies to a single package.
- ambiguous imports and static imports (like using the same classname twice from different packages) will cause compiler errors.
- To import inner classes, we can specify the name or a wildcard after the outer class name e.g. import java.util.Map.*;
Static imports
- Used to alias a class's static members (field's and methods)
- Has to be "import static" only
- Can only be used to import a classes fields. Static import of only a CLASS IS ILLEGAL.
- Enum constants can be static imported so that they can be used without type name.
- wildcards can be used
- e.g.
import java.util.*;
import static java.lang.System.out;
import static java.lang.Thread.MAX_PRIORITY;
import static java.util.Collections.*;
//import static java.lang.System; //ILLEGAL
public class SITest {
public static void main(String[] args) {
out.println("A thread's max priority is " + MAX_PRIORITY); //instead of System.out.println(Thread.MAX_PRIORITY);
List<String> aList = new ArrayList<String>();
sort(aList); //Instead of Collections.sort
binarySearch(aList,"key"); //Instead of Collections.binarySearch
}
}