📄 chap05.htm
字号:
<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\simple, 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>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I23'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I24>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Setting the CLASSPATH has been such a
trial for beginning Java users (it was for me, when I started) that Sun made the
JDK in Java 2 a bit smarter. You’ll find that, when you install it, even
if you don’t set a CLASSPATH you’ll be able to compile and run basic
Java programs. To compile and run the source-code package for this book
(available on the CD ROM packaged with this book, or at
<I>www.BruceEckel.com</I>), however, you will need to make some modifications to
your CLASSPATH (these are explained in the source-code package).
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I24'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I25>
</FONT><BR></P></DIV>
<A NAME="Heading192"></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="Index492"></A><A NAME="Index493"></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.simple.*;
<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 you
don’t write the code that actually causes the collision, everything is
OK—this is good because otherwise you might end up doing a lot of typing
to prevent collisions that would never happen.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I25'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I26>
</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>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I26'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I27>
</FONT><A NAME="_Toc375545293"></A><A NAME="_Toc481064591"></A><BR></P></DIV>
<A NAME="Heading193"></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>//: com:bruceeckel:tools:P.java</font>
<font color=#009900>// The P.rint & P.rintln shorthand.</font>
<font color=#0000ff>package</font> com.bruceeckel.tools;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> P {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> rint(String s) {
System.out.print(s);
}
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> rintln(String s) {
System.out.println(s);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can use this shorthand to print a
<B>String</B> either with a newline (<B>P.rintln( )</B>) or without a
newline (<B>P.rint( )</B>).<A NAME="AAASpellcheck"></A>
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I27'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I28>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">You can guess that the location of this
file must be in a directory that starts at one of the CLASSPATH locations, then
continues <B>com/bruceeckel/tools</B>. After compiling, the <B>P.class</B> file
can be used anywhere on your system with an <B>import</B>
statement:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: c05:ToolTest.java</font>
<font color=#009900>// Uses the tools library.</font>
<font color=#0000ff>import</font> com.bruceeckel.tools.*;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> ToolTest {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
P.rintln(<font color=#004488>"Available from now on!"</font>);
P.rintln(<font color=#004488>""</font> + 100); <font color=#009900>// Force it to be a String</font>
P.rintln(<font color=#004488>""</font> + 100L);
P.rintln(<font color=#004488>""</font> + 3.14159);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Notice that all objects can easily be
forced into <B>String</B> representations by putting them in a <B>String
</B>expression; in the above case, starting the expression with an empty
<B>String </B>does the trick. But this brings up an interesting observation. If
you call <B>System.out.println(100)</B>, it works without casting it to a
<B>String</B>. With some extra overloading, you can get the <B>P</B> class to do
this as well (this is an exercise at the end of this chapter).
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I28'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I29>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">So from now on, whenever you come up with
a useful new utility, you can add it to the <B>tools</B> directory. (Or to your
own personal <B>util</B> or <B>tools</B> directory.)
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I29'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I30>
</FONT><A NAME="_Toc375545294"></A><A NAME="_Toc481064592"></A><BR></P></DIV>
<A NAME="Heading194"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Using imports to change behavior</H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">A feature that is missing from Java is
C’s <I>conditional compilation</I>, which allows you to change a switch
and get different behavior without changing any other code. The reason such a
feature was left out of Java is probably because it is most often used in C to
solve cross-platform issues: different portions of the code are compiled
depending on the platform that the code is being compiled for. Since Java is
intended to be automatically cross-platform, such a feature should not be
necessary.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I30'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I31>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">However, there are other valuable uses
for conditional compilation. A very common use is for debugging code. The
debugging features are enabled during development, and disabled in the shipping
product. Allen Holub (<I>www.holub.com</I>) came up with the idea of using
packages to mimic conditional compilation. He used this to create a Java version
of C’s very useful <I>assertion mechanism</I>, whereby you can say
“this should be true” or “this should be false” and if
the statement doesn’t agree with your assertion you’ll find out
about it. Such a tool is quite helpful during debugging.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I31'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I32>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Here is the class that you’ll use
for debugging:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:tools:debug:Assert.java</font>
<font color=#009900>// Assertion tool for debugging.</font>
<font color=#0000ff>package</font> com.bruceeckel.tools.debug;
<font color=#0000ff>public</font> <font color=#0000ff>class</font> Assert {
<font color=#0000ff>private</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> perr(String msg) {
System.err.println(msg);
}
<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> is_true(<font color=#0000ff>boolean</font> exp) {
<font color=#0000ff>if</font>(!exp) perr(<font color=#004488>"Assertion failed"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> is_false(<font color=#0000ff>boolean</font> exp){
<font color=#0000ff>if</font>(exp) perr(<font color=#004488>"Assertion failed"</font>);
}
<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font>
is_true(<font color=#0000ff>boolean</font> exp, String msg) {
<font color=#0000ff>if</font>(!exp) perr(<font color=#004488>"Assertion failed: "</font> + msg);
}
<font color=#0000ff>public</font> <font color=#0000ff>final</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font>
is_false(<font color=#0000ff>boolean</font> exp, String msg) {
<font color=#0000ff>if</font>(exp) perr(<font color=#004488>"Assertion failed: "</font> + msg);
}
} <font color=#009900>///:~</font></PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">This class simply encapsulates Boolean
tests, which print error messages if they fail. In Chapter 10, you’ll
learn about a more sophisticated tool for dealing with errors called
<I>exception handling</I>, but the <B>perr( )</B> method will work fine in
the meantime.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I32'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I33>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The output is printed to the console
<I>standard error</I> stream by writing to <B>System.err</B>.
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I33'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I34>
</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">When you want to use this class, you add
a line in your program:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#0000ff>import</font> com.bruceeckel.tools.debug.*;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To remove the assertions so you can ship
the code, a second <B>Assert</B> class is created, but in a different package:
</backtalk:display>
[ <a href='http://www.mindview.net/backtalk/CommentServlet?ID=TIJ3_CHAPTER5_I34'
target="_blank">Add Comment</a> ]
<backtalk:display ID=TIJ3_CHAPTER5_I35>
</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: com:bruceeckel:tools:Assert.java</font>
<font color=#009900>// Turning off the assertion output </font>
<font color=#009900>// so you can ship the program.</font>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -