chapter05.html
来自「java 是一个很好的网络开发环境。由于它是通过解释的方法」· HTML 代码 · 共 1,008 行 · 第 1/5 页
HTML
1,008 行
<font color=#009900>// . . .</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Now, if someone wants to use
<B>MyClass</B> or, for that matter, any of the other <B>public</B> classes in
<B>mypackage</B>, they must use the <B>import</B> keyword to make the name or
names in <B>mypackage</B> available. The alternative is to give the
fully-qualified name:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>mypackage.MyClass m = <font color=#0000ff>new</font> mypackage.MyClass();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The <B>import</B> keyword can make
this much cleaner:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>import</font> mypackage.*;
<font color=#009900>// . . . </font>
MyClass m = <font color=#0000ff>new</font> MyClass();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">It’s worth keeping in mind
that what the <B>package</B> and <B>import</B> keywords allow you to do, as a
library designer, is to divide up the single global name space so you
won’t have clashing names, no matter how many people get on the Internet
and start writing classes in
Java.</FONT><A NAME="_Toc375545292"></A><A NAME="_Toc408018495"></A><BR></P></DIV>
<A NAME="Heading162"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Creating unique package names</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You might observe that, since a
package never really gets “packaged” into a single file, a package
could be made up of many <B>.class</B> files, and things could get a bit
cluttered. To prevent this, a logical thing to do is to place all the
<B>.class</B> 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.
<A NAME="Index365"></A><A NAME="Index366"></A></FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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 <B>.class</B> file into
the name of the <B>package</B>. The compiler enforces this, but by convention,
the first part of the <B>package</B> name is the Internet domain name of the
creator of the class, reversed. Since Internet domain names are guaranteed to be
unique (by
InterNIC,</FONT><A NAME="fnB24" HREF="#fn24">[24]</A><FONT FACE="Georgia">
who controls their assignment) <I>if</I> you follow this convention it’s
guaranteed that your <B>package</B> 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.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The second part of this trick is
resolving the <B>package</B> name into a directory on your machine, so when the
Java program runs and it needs to
<A NAME="Index367"></A><A NAME="Index368"></A>load the <B>.class </B>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 <B>static
</B>member of the class), it can locate the directory where the <B>.class
</B>file resides.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The Java interpreter proceeds as
follows. First, it finds the environment variable
<A NAME="Index369"></A>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 <B>.class</B>
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 <B>package foo.bar.baz</B> becomes <B>foo\bar\baz </B>or <B>foo/bar/baz
</B>depending on your operating system). This is then concatenated to the
various entries in the CLASSPATH. That’s where it looks for the
<B>.class</B> 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).</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To understand this, consider my
domain name, which is <B>bruceeckel.com</B>. By reversing this,
<B>com.bruceeckel</B> 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<A NAME="Index370"></A> so the entire package name
is lowercase.) I can further subdivide this by deciding that I want to create a
library named <B>util</B>, so I’ll end up with a package
name:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>package</font> com.bruceeckel.util;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Now this package name can be used
as an umbrella name space for the following two files:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: Vector.java</font>
<font color=#009900>// Creating a package</font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Vector {
<font color=#0000ff>public</font> Vector() {
System.out.println(
<font color=#004488>"com.bruceeckel.util.Vector"</font>);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you create your own packages,
you’ll discover that the <B>package</B> statement must be the first
non-comment code in the file. The second file looks much the
same:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: List.java</font>
<font color=#009900>// Creating a package </font>
<font color=#0000ff>package</font> com.bruceeckel.util;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> List {
<font color=#0000ff>public</font> List() {
System.out.println(
<font color=#004488>"com.bruceeckel.util.List"</font>);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Both of these files are placed in
the subdirectory on my system:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>C:\DOC\JavaT\com\bruceeckel\util</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If you walk back through this, you
can see the package name <B>com.bruceeckel.util</B>, but what about the first
portion of the path? That’s taken care of in the CLASSPATH environment
variable, which is, on my machine:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>CLASSPATH=.;D:\JAVA\LIB;C:\DOC\JavaT</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">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
<A NAME="Index371"></A>JAR named <B>grape.jar</B> your classpath would
include:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>CLASSPATH=.;D:\JAVA\LIB;C:\flavors\grape.jar</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Once the classpath is set up
properly, the following file can be placed in any directory:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: LibTest.java</font>
<font color=#009900>// Uses the library</font>
<font color=#0000ff>package</font> c05;
<font color=#0000ff>import</font> com.bruceeckel.util.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> LibTest {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
Vector v = <font color=#0000ff>new</font> Vector();
List l = <font color=#0000ff>new</font> List();
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When the compiler encounters the
<B>import</B> statement, it begins searching at the directories specified by
CLASSPATH, looking for subdirectory com\bruceeckel\util, then seeking the
compiled files of the appropriate names (<B>Vector.class</B> for <B>Vector</B>
and <B>List.class</B> for <B>List</B>). Note that both the classes and the
desired methods in <B>Vector</B> and <B>List</B> must be
<B>public</B>.</FONT><BR></P></DIV>
<A NAME="Heading163"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Automatic compilation</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The first time you create an object
of an imported class (or you access a <B>static</B> member of a class), the
compiler will hunt for the <B>.class</B> file of the same name (so if
you’re creating an object of class <B>X</B>, it looks for <B>X.class</B>)
in the appropriate directory. If it finds only<B> X.class</B>, that’s what
it must use. However, if it also finds an <B>X.java</B> in the same directory,
the compiler will compare the date stamp on the two files, and if <B>X.java</B>
is more recent than <B>X.class</B>, it will
<A NAME="Index372"></A><A NAME="Index373"></A><I>automatically recompile
</I><B>X<I>.</I>java</B> to generate an up-to-date
<B>X.class</B>.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">If a class is not in a <B>.java</B>
file of the same name as that class, this behavior will not occur for that
class.</FONT><BR></P></DIV>
<A NAME="Heading164"></A><FONT FACE = "Verdana"><H4 ALIGN="LEFT">
Collisions</H4></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">What happens if two libraries are
imported via * and they include the same
<A NAME="Index374"></A><A NAME="Index375"></A>names? For example, suppose a
program does this:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>import</font> com.bruceeckel.util.*;
<font color=#0000ff>import</font> java.util.*;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Since <B>java.util.*</B> also
contains a <B>Vector</B> 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.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The collision <I>does</I> occur if
you now try to make a <B>Vector</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>Vector v = <font color=#0000ff>new</font> Vector();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Which <B>Vector</B> 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 <B>Vector</B>, for example, I must say:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>java.util.Vector v = <font color=#0000ff>new</font> java.util.Vector();</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Since this (along with the
CLASSPATH) completely specifies the location of that <B>Vector</B>,
there’s no need for the <B>import java.util.*</B> statement unless
I’m using something else from
<B>java.util</B>.</FONT><A NAME="_Toc375545293"></A><A NAME="_Toc408018496"></A><BR></P></DIV>
<A NAME="Heading165"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
A custom tool library<A NAME="COM_EckelObjects_tools"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">With this knowledge, you can now
create your own libraries of tools to reduce or eliminate duplicate code.
Consider, for example, creating an alias for <B>System.out.println( )</B>
to reduce typing. This can be part of a package called
<B>tools</B>:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: P.java</font>
<font color=#009900>// The P.rint & P.rintln shorthand</font>
<font color=#0000ff>package</font> com.bruceeckel.tools;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?