📄 chapter08.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<!--
This document was converted from RTF source:
By rtftohtml 4.19
See http://www.sunpack.com/RTF
Filename:Tjava14.rtf
Application Directory:c:\TOOLS\RTF2HTML\
Subject:
Author:Bruce Eckel
Operator:Bruce Eckel
Document Comments:
Version Comments:
Comments:
Keywords:
Translation Date:02/04/2000
Translation Time:23:25:01
Translation Platform:Win32
Number of Output files:27
This File:Chapter08.html
SplitDepth=1
SkipNavPanel=1
SkipLeadingToc=1
SkipTrailingToc=1
GenContents=1
GenFrames=1
GenIndex=1
-->
<HEAD lang="en"><META http-equiv="Content-Type" content="text/html">
<TITLE>8: Holding your objects</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF"><DIV ALIGN="CENTER">
<a href="http://www.MindView.net">
<img src="mindview-head.gif" alt="MindView Inc." BORDER = "0"></a>
<CENTER>
<FONT FACE="Verdana" size = "-1">
[ <a href="README-HTML.txt">Viewing Hints</a> ]
[ <a href="http://www.mindview.net/TIJ2/index.html">2nd Edition</a> ]
[ <a href="http://www.mindview.net/MailingList.html">Free Newsletter</a> ] <br>
[ <a href="http://www.mindview.net/Training.html">Seminars</a> ]
[ <a href="http://www.mindview.net/javaCD2.html">Seminars on CD ROM</a> ]
[ <a href="http://www.mindview.net/CPPServices/#ConsultingServices">Consulting</a> ]
</FONT>
<H2><FONT FACE="Verdana">
Thinking in Java, 1st edition</FONT></H2>
<H3><FONT FACE="Verdana">©1998 by Bruce Eckel</FONT></H3>
<FONT FACE="Verdana" size = "-1">
[ <a href="Chapter07.html">Previous Chapter</a> ]
[ <a href="SimpleContents.html">Short TOC</a> ]
[ <a href="Contents.html">Table of Contents</a> ]
[ <a href="DocIndex.html">Index</a> ]
[ <a href="Chapter09.html">Next Chapter</a> ]
</FONT>
</CENTER>
</P></DIV><A NAME="Chapter_8"></A><A NAME="_Toc375545346"></A><A NAME="_Toc407441452"></A><A NAME="_Toc408018562"></A><A NAME="Heading239"></A><FONT FACE = "Verdana"><H1 ALIGN="LEFT">
8: Holding <BR>your objects<A NAME="OLE_LINK2"></A></H1></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Verdana" SIZE=4>It’s a fairly
simple program that has only a fixed quantity of objects with known
lifetimes.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">In general, your programs will
always be creating new objects based on some criteria that will be known only at
the time the program is running. You won’t know until run-time the
quantity or even the exact type of the objects you need. To solve the general
programming problem, you need to create any number of objects, anytime,
anywhere. So you can’t rely on creating a named handle to hold each one of
your objects:</FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE>MyObject myHandle;</PRE></FONT></BLOCKQUOTE>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">since you’ll never know how
many of these things you’ll actually need.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">To solve this rather essential
problem, Java has several ways to hold objects (or rather, handles to objects).
The built-in type is the array, which has been discussed before and will get
additional coverage in this chapter. Also, the Java utilities library has some
<A NAME="Index716"></A><I>collection classes</I> (also known as
<A NAME="Index717"></A><I>container classes</I>, but that term is used by the
AWT so “collection” will be used here) that provide more
sophisticated ways to hold and even manipulate your objects. This will comprise
the remainder of this
chapter.</FONT><A NAME="_Toc375545347"></A><A NAME="_Toc408018563"></A><BR></P></DIV>
<A NAME="Heading240"></A><FONT FACE = "Verdana"><H2 ALIGN="LEFT">
Arrays</H2></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Most of the necessary introduction
to <A NAME="Index718"></A>arrays is in the last section of Chapter 4, which
shows how you define and initialize an array. Holding objects is the focus of
this chapter, and an array is just one way to hold objects. But there are a
number of other ways to hold objects, so what makes an array
special?</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">There are two issues that
distinguish arrays from other types of collections:
<A NAME="Index719"></A>efficiency and <A NAME="Index720"></A>type. The array is
the most efficient way that Java provides to store and access a sequence of
objects (actually, object handles). The array is a simple linear sequence, which
makes element access fast, but you pay for this speed: when you create an array
object, its size is fixed and cannot be changed for the lifetime of that array
object. You might suggest creating an array of a particular size and then, if
you run out of space, creating a new one and moving all the handles from the old
one to the new one. This is the behavior of the <B>Vector</B> class, which will
be studied later in the chapter. However, because of the overhead of this size
flexibility, a <B>Vector</B> is measurably less efficient than an
array.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The
<A NAME="Index721"></A><B>vector</B> class in C++ <I>does</I> know the type of
objects it holds, but it has a different drawback when compared with arrays in
Java: the C++ <B>vector</B>’s <B>operator[]</B> doesn’t do bounds
checking, so you can run past the end. (It’s possible, however, to ask how
big the <B>vector</B> is, and the <B>at( )</B> method <I>does</I> perform
bounds checking.) In Java, you get bounds checking regardless of whether
you’re using an array or a collection – you’ll get a
<A NAME="Index722"></A><B>RuntimeException</B> if you exceed the bounds. As
you’ll learn in Chapter 9, this type of exception indicates a programmer
error and thus you don’t need to check for it in your code. As an aside,
the reason the C++ <B>vector</B> doesn’t check bounds with every access is
speed – in Java you have the constant performance overhead of bounds
checking all the time for both arrays and collections.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The other generic collection
classes that will be studied in this chapter,
<A NAME="Index723"></A><B>Vector</B>, <A NAME="Index724"></A><B>Stack</B>, and
<A NAME="Index725"></A><B>Hashtable</B>, all deal with objects as if they had no
specific type. That is, they treat them as type
<A NAME="Index726"></A><B>Object</B>, the root class of all classes in Java.
This works fine from one standpoint: you need to build only one collection, and
any Java object will go into that collection. (Except for primitives –
these can be placed in collections as constants using the Java primitive wrapper
classes, or as changeable values by wrapping in your own class.) This is the
second place where an array is superior to the generic collections: when you
create an array, you create it to hold a specific type. This means that you get
compile-time type checking to prevent you from putting the wrong type in, or
mistaking the type that you’re extracting. Of course, Java will prevent
you from sending an inappropriate message to an object, either at compile-time
or at run-time. So it’s not as if it’s riskier one way or the other,
it’s just nicer if the compiler points it out to you, faster at run-time,
and there’s less likelihood that the end user will get surprised by an
exception.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">For efficiency and type checking
it’s always worth trying to use an array if you can. However, when
you’re trying to solve a more general problem arrays can be too
restrictive. After looking at arrays, the rest of this chapter will be devoted
to the collection classes provided by
Java.</FONT><A NAME="_Toc375545348"></A><A NAME="_Toc408018564"></A><BR></P></DIV>
<A NAME="Heading241"></A><FONT FACE = "Verdana"><H3 ALIGN="LEFT">
Arrays are first-class
objects<BR><A NAME="Index727"></A><A NAME="Index728"></A></H3></FONT>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">Regardless of what type of array
you’re working with, the array identifier is actually a handle to a true
object that’s created on the heap. The heap object can be created either
implicitly, as part of the array initialization syntax, or explicitly with a
<B>new</B> expression. Part of the heap object (in fact, the only field or
method you can access) is the read-only <B>length</B> member that tells you how
many elements can be stored in that array object.
<A NAME="Index729"></A><A NAME="Index730"></A>The ‘<B>[]</B>’ syntax
is the only other access that you have to the array object.</FONT><BR></P></DIV>
<DIV ALIGN="LEFT"><P><FONT FACE="Georgia">The following example shows the
various ways that an array can be initialized, and how the array handles can be
assigned to different array objects. It also shows that
<A NAME="Index731"></A>arrays of objects and <A NAME="Index732"></A>arrays of
primitives are almost identical in their use. The only difference is that arrays
of objects hold handles while arrays of primitives hold the primitive values
directly. </FONT><BR></P></DIV>
<BLOCKQUOTE><FONT SIZE = "+1"><PRE><font color=#009900>//: ArraySize.java</font>
<font color=#009900>// Initialization & re-assignment of arrays</font>
<font color=#0000ff>package</font> c08;
<font color=#0000ff>class</font> Weeble {} <font color=#009900>// A small mythical creature</font>
<font color=#0000ff>public</font> <font color=#0000ff>class</font> ArraySize {
<font color=#0000ff>public</font> <font color=#0000ff>static</font> <font color=#0000ff>void</font> main(String[] args) {
<font color=#009900>// Arrays of objects:</font>
Weeble[] a; <font color=#009900>// Null handle</font>
Weeble[] b = <font color=#0000ff>new</font> Weeble[5]; <font color=#009900>// Null handles</font>
Weeble[] c = <font color=#0000ff>new</font> Weeble[4];
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < c.length; i++)
c[i] = <font color=#0000ff>new</font> Weeble();
Weeble[] d = {
<font color=#0000ff>new</font> Weeble(), <font color=#0000ff>new</font> Weeble(), <font color=#0000ff>new</font> Weeble()
};
<font color=#009900>// Compile error: variable a not initialized:</font>
<font color=#009900>//!System.out.println("a.length=" + a.length);</font>
System.out.println(<font color=#004488>"b.length = "</font> + b.length);
<font color=#009900>// The handles inside the array are </font>
<font color=#009900>// automatically initialized to null:</font>
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < b.length; i++)
System.out.println(<font color=#004488>"b["</font> + i + <font color=#004488>"]="</font> + b[i]);
System.out.println(<font color=#004488>"c.length = "</font> + c.length);
System.out.println(<font color=#004488>"d.length = "</font> + d.length);
a = d;
System.out.println(<font color=#004488>"a.length = "</font> + a.length);
<font color=#009900>// Java 1.1 initialization syntax:</font>
a = <font color=#0000ff>new</font> Weeble[] {
<font color=#0000ff>new</font> Weeble(), <font color=#0000ff>new</font> Weeble()
};
System.out.println(<font color=#004488>"a.length = "</font> + a.length);
<font color=#009900>// Arrays of primitives:</font>
<font color=#0000ff>int</font>[] e; <font color=#009900>// Null handle</font>
<font color=#0000ff>int</font>[] f = <font color=#0000ff>new</font> <font color=#0000ff>int</font>[5];
<font color=#0000ff>int</font>[] g = <font color=#0000ff>new</font> <font color=#0000ff>int</font>[4];
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < g.length; i++)
g[i] = i*i;
<font color=#0000ff>int</font>[] h = { 11, 47, 93 };
<font color=#009900>// Compile error: variable e not initialized:</font>
<font color=#009900>//!System.out.println("e.length=" + e.length);</font>
System.out.println(<font color=#004488>"f.length = "</font> + f.length);
<font color=#009900>// The primitives inside the array are</font>
<font color=#009900>// automatically initialized to zero:</font>
<font color=#0000ff>for</font>(<font color=#0000ff>int</font> i = 0; i < f.length; i++)
System.out.println(<font color=#004488>"f["</font> + i + <font color=#004488>"]="</font> + f[i]);
System.out.println(<font color=#004488>"g.length = "</font> + g.length);
System.out.println(<font color=#004488>"h.length = "</font> + h.length);
e = h;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -