|
The Java platform consists of packages of related classes and interfaces. For example, all the classes that deal with I/O are in the Java.io package; the utility classes are all grouped in the java.util package; and so on. If you become involved in a large software development project in Java, you'd want to organize your own classes into packages.
In this section, we will first show how a package supplied with the Java platform is used in your own program. Then we will discuss how you can create your own packages.
The following program is a simple demonstration of how a package that comes with the Java platform can be used in your own program. The program first declares and initializes an array of integers in lines (B) and (C). Subsequently, in line (E), this array is sorted by invoking the highly efficient sort method defined for the class Arrays in the java.util package. Finally, the program reports back the time taken for sorting in line (G).
//SortTiming.java import java.util.*; //(A) public class Test { public static void main( String [] args ) { int[] arr = new int[1000000]; //(B) for ( int i=0; i<1000000; i++ ) arr[i] = (int) ( 1000000 * Math.random() ); //(C) long startTime = System.currentTimeMillis(); //(D) Arrays.sort( arr ); //(E) long diffTime = System.currentTimeMillis() - startTime; //(F) System.out.println("Sort time in millisecs: " + diffTime);//(G) } }
For line (E) to make any sense to the compiler, the program starts in line (A) with the statement
import java.util.*;
for importing the java.util package that contains the class Arrays. With the import statement as shown in line (A), our program will be able to refer to any class in the java.util package by its name directly. Without the import statement, we would need to replace the statement in line (E) by
java.util.Arrays.sort( arr );
Therefore, when your program includes an import statement for a certain package, you just make it easier to refer to the classes in that package. If for some reason you decide to use a class without importing the package containing the class, then you have no choice but to use what's known as the package qualified name for that class, as, for example, by java.util.Arrays for the Arrays class in the java.util package.
The program also uses a couple of other classes, Math and System. Both these classes are in the java.lang package which gets automatically imported into every Java program. The class Math is needed in line (C) for the invocation of random() to fill up a million-element array with random numbers.[9] And the class System makes available the method currentTimeMillis(), used in lines (D) and (F), which returns the current time in milliseconds from midnight January 1, 1970. A particular run of the program on a 4-processor UltraSparc produced the following output:
Sort time in millisecs: 1378
The rest of this section is devoted to how you can create and use your own packages. To illustrate the various issues related to package creation and usage, let's say that we want to create the following three packages with classes therein as shown:
packageX: contains classes TestOne and TestTwo packageY: contains class TestOne testDirectory: contains class TestFinal
In order to create a name conflict, we have intentionally named one of the classes in packageX the same as the sole class in packageY. The TestOne class in packageX is meant to be different from the TestOne class in packageY.
We will now provide simple definitions for the four classes listed above. As could be the case during code development, for testing purposes you would want to compile and execute the classes in the directories in which they exist. With respect to class definition, compilation, and execution, the reader should note the following:
How a statement like
package packageX;
is used at the top of a class file to name the package in which a class resides.
How a class sometimes needs both a package statement of the kind shown above and an import statement for the same package. This happens when a class needs to use other classes within the same newly created package.
Using the classpath option for either the java command or both the javac and the java commands when we import a user-created package into a program.
When two different packages contain classes of the same name, how we can avoid name conflict by using package qualified names for the classes.
We now ask the reader to carry out the following steps:
In any directory in which you like to do Java programming, create the following three subdirectories:
packageX packageY testDirectory
In the directory packageX, create the class TestOne in a file named TestOne.java:
//TestOne.java package packageX; //(A) public class TestOne { public void print() { System.out.println( "print of packageX.TestOne invoked" ); } public static void main( String[] args ) { TestOne testone = new TestOne(); testone.print(); } }
Note the statement in line (A) at the top of the class file
package packageX;
that tells the Java platform that this class will reside in a package named packageX. This class can be compiled by
javac TestOne.Java
If you wanted to execute this class while you are in the directory packageX, you'll have to invoke the Java Virtual Machine with the -classpath option, as for example in
java -classpath .:/chap3/packageStudy.d packageX.TestOne
which is based on the assumption that the three package directories you created are in the directory packageStudy.d.
Create in the same directory, packageX, the following class in a file named TestTwo.Java:
//TestTwo. java package packageX; //(B) import packageX.*; //(C) public class TestTwo { TestOne testone = new TestOne(); //(D) public void print() { System.out.println ( "print of packageX. TestTwo invoked" ); } public static void main( String[] args ) { TestTwo testtwo = new TestTwo(); testtwo.print(); testtwo.testone.print(); } }
Note that this class contains both a package statement, in line (B), that says that the class resides in package packageX and an import statement in line (C). The import statement is needed because the class has a data member of type TestOne in line (D) which is defined in the package packageX. To compile this class, you'd now need to use the -classpath option, as for example in
javac -classpath .:/chap3/packageStudy.d TestTwo.java
The classpath tells the compiler how to go about locating packageX needed by the import statement of the class. Executing the class with the java command will also need the -classpath option, as for example in
java -classpath .:/chap3/packageStudy.d packageX.TestTwo
Now switch over to the directory packageY and, in order to create a name conflict with packageX, install in this directory a class named TestOne in a file named TestOne.Java:
//TestOne.java package packageY; //(E) public class TestOne { public void print() { System.out.println( "print of packageY.TestOne invoked" ); } public static void main( String[] args ) { TestOne testone = new TestOne(); testone.print(); } }
Note the declaration of packageY in line (E) at the top of the class file. As long as you are in the packageY directory, you can compile this class by
javac TestOne.java
And you can execute the class by something like this
java -classpath .:/chap3/packageStudy.d packageY.TestOne
Now switch over to the directory testDirectory and create in it a class named TestFinal in a file called TestFinal.java:
//TestFinal.java import packageX.*; //(F) public class TestFinal { packageX.TestOne testone_X = new packageX.TestOne(); //(G) packageY.TestOne testone_Y = new packageY.TestOne(); //(H) TestTwo testtwo = new TestTwo(); //(I) void print() { System.out.println( "print of TestFinal invoked" ); } public static void main( String[] args ) { TestFinal tf = new TestFinal(); tf.print(); tf.testone_X.print(); tf.testone_Y.print(); tf.testtwo.print(); } }
Note how the package qualified names are used in lines (G) and (H) to tell the compiler which TestOne class is used where. Also note that the import statement in line (F) is needed for the unqualified class name in line (I). To compile the file TestFinal.java, you'd need to use the -classpath option to help the compiler locate the packages packageX and packageY:
javac -classpath .:/chap3/packageStudy.d TestFinal.java
To execute TestFinal, you'd again need to use the -classpath option, as in
java -classpath .:/chap3/packageStudy.d TestFinal
Executing this class produces the expected output:
print of TestFinal invoked print of packageX.TestOne invoked print of packageY.TestOne invoked print of packageX.TestTwo invoked
[9]Math.random() returns a double that is greater than or equal to 0.0 and less than 1.0. The statistical distribution of these pseudorandomly generated numbers is uniform over this range.
|