CATEGORII DOCUMENTE |
Asp | Autocad | C | Dot net | Excel | Fox pro | Html | Java |
Linux | Mathcad | Photoshop | Php | Sql | Visual studio | Windows | Xml |
You might observe that, since a package never really gets "packaged" into a single file, a package could be made up of many .class files, and things could get a bit cluttered. To prevent this, a logical thing to do is to place all the .class files for a particular package into a single directory; that is, use the hierarchical file structure of the operating system to your advantage. This is how Java handles the problem of clutter.
It also solves two other problems: creating unique package names and finding those classes that might be buried in a directory structure someplace. This is accomplished, as was introduced in Chapter 2, by encoding the path of the location of the .class file into the name of the package. The compiler enforces this, but by convention, the first part of the package name is the Internet domain name of the creator of the class, reversed. Since Internet domain names are guaranteed to be unique (by InterNIC, who controls their assignment) if you follow this convention it's guaranteed that your package name will be unique and thus you'll never have a name clash. (That is, until you lose the domain name to someone else who starts writing Java code with the same path names as you did.) Of course, if you don't have your own domain name then you must fabricate an unlikely combination (such as your first and last name) to create unique package names. If you've decided to start publishing Java code it's worth the relatively small effort to get a domain name.
The second part of this trick is resolving the package name into a directory on your machine, so when the Java program runs and it needs to load the .class file (which it does dynamically, at the point in the program where it needs to create an object of that particular class, or the first time you access a static member of the class), it can locate the directory where the .class file resides.
The Java interpreter proceeds as follows. First, it finds the environment variable CLASSPATH (set via the operating system when Java, or a tool like a Java-enabled browser, is installed on a machine). CLASSPATH contains one or more directories that are used as roots for a search for .class files. Starting at that root, the interpreter will take the package name and replace each dot with a slash to generate a path name from the CLASSPATH root (so package foo.bar.baz becomes foobarbaz or foo/bar/baz depending on your operating system). This is then concatenated to the various entries in the CLASSPATH. That's where it looks for the .class file with the name corresponding to the class you're trying to create. (It also searches some standard directories relative to where the Java interpreter resides).
To understand this, consider my domain name, which is bruceeckel.com. By reversing this, com.bruceeckel establishes my unique global name for my classes. (The com, edu, org, etc. extension was formerly capitalized in Java packages, but this was changed in Java 1.2 so the entire package name is lowercase.) I can further subdivide this by deciding that I want to create a library named util, so I'll end up with a package name:
package com.bruceeckel.util;
Now this package name can be used as an umbrella name space for the following two files:
//: Vector.java
// Creating a package
package com.bruceeckel.util;
public class Vector
When you create your own packages, you'll discover that the package statement must be the first non-comment code in the file. The second file looks much the same:
//: List.java
// Creating a package
package com.bruceeckel.util;
public class List
Both of these files are placed in the subdirectory on my system:
C:DOCJavaTcombruceeckelutil
If you walk back through this, you can see the package name com.bruceeckel.util, but what about the first portion of the path? That's taken care of in the CLASSPATH environment variable, which is, on my machine:
CLASSPATH=.;D:JAVALIB;C:DOCJavaT
You can see that the CLASSPATH can contain a number of alternative search paths. There's a variation when using JAR files, however. You must put the name of the JAR file in the classpath, not just the path where it's located. So for a JAR named grape.jar your classpath would include:
CLASSPATH=.;D:JAVALIB;C:flavorsgrape.jar
Once the classpath is set up properly, the following file can be placed in any directory: (See page if you have trouble executing this program.):
//: LibTest.java
// Uses the library
package c05;
import com.bruceeckel.util.*;
public class LibTest
When the compiler encounters the import statement, it begins searching at the directories specified by CLASSPATH, looking for subdirectory combruceeckelutil, then seeking the compiled files of the appropriate names (Vector.class for Vector and List.class for List). Note that both the classes and the desired methods in Vector and List must be public.
The first time you create an object of an imported class (or you access a static member of a class), the compiler will hunt for the .class file of the same name (so if you're creating an object of class X, it looks for X.class) in the appropriate directory. If it finds only X.class, that's what it must use. However, if it also finds an X.java in the same directory, the compiler will compare the date stamp on the two files, and if X.java is more recent than X.class, it will automatically recompile X.java to generate an up-to-date X.class.
If a class is not in a .java file of the same name as that class, this behavior will not occur for that class.
What happens if two libraries are imported via * and they include the same names? For example, suppose a program does this:
import com.bruceeckel.util.*;
import java.util.*;
Since java.util.* also contains a Vector class, this causes a potential collision. However, as long as the collision doesn't actually occur, everything is OK - this is good because otherwise you might end up doing a lot of typing to prevent collisions that would never happen.
The collision does occur if you now try to make a Vector:
Vector v = new Vector();
Which Vector class does this refer to? The compiler can't know, and the reader can't know either. So the compiler complains and forces you to be explicit. If I want the standard Java Vector, for example, I must say:
java.util.Vector v = new java.util.Vector();
Since this (along with the CLASSPATH) completely specifies the location of that Vector, there's no need for the import java.util.* statement unless I'm using something else from java.util.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 744
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved