⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tij0120.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 4 页
字号:
<TD WIDTH=95 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">Integer.TYPE</FONT></TT><P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD WIDTH=89 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">long.class</FONT></TT><P></DIV>
</TD>
<TD WIDTH=95 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">Long.TYPE</FONT></TT><P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD WIDTH=89 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">float.class</FONT></TT><P></DIV>
</TD>
<TD WIDTH=95 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">Float.TYPE</FONT></TT><P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD WIDTH=89 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">double.class</FONT></TT><P></DIV>
</TD>
<TD WIDTH=95 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">Double.TYPE</FONT></TT><P></DIV>
</TD>
</TR>
<TR VALIGN="TOP">
<TD WIDTH=89 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">void.class</FONT></TT><P></DIV>
</TD>
<TD WIDTH=95 COLSPAN=1 ROWSPAN=1 VALIGN=TOP>
<DIV ALIGN=LEFT><TT><FONT FACE="Courier New" SIZE=3 COLOR="Black">Void.TYPE</FONT></TT><P></DIV>
</TD>
</TR>
<a name="_Toc375545408"></a><a name="_Toc408018647"></a></TABLE></DIV>
<A NAME="Heading356"></A><H3 ALIGN=LEFT>
Checking
before a cast
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">So
far, you&#8217;ve seen RTTI forms including:
</FONT><P></DIV>
<OL>
<LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	The
classic cast, e.g. &#8220;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>(Shape),</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8221;
which uses RTTI to make sure the cast is correct and throws a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ClassCastException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
if you&#8217;ve performed a bad cast.
</FONT><LI><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">	The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object representing the type of your object. The 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object can be queried for useful runtime information.
</FONT></OL><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
C++, the classic cast &#8220;
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>(Shape)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">&#8221;
does 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">perform
RTTI. It simply tells the compiler to treat the object as the new type. In
Java, which does perform the type check, this cast is often called a
&#8220;type safe downcast<A NAME="Index1378"></A><A NAME="Index1379"></A><A NAME="Index1380"></A>.&#8221;
The reason for the term &#8220;downcast&#8221; is the historical arrangement of
the class hierarchy diagram. If casting a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is an upcast, then casting a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a downcast. However, you know a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is also a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
and the compiler freely allows an upcast assignment, but you 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>don&#8217;t</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
know that a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Shape</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is necessarily a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Circle</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
so the compiler doesn&#8217;t allow you to perform a <A NAME="Index1381"></A><A NAME="Index1382"></A>downcast
assignment without using an explicit cast. 
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There&#8217;s
a third form of RTTI in Java. This is the <A NAME="Index1383"></A><A NAME="Index1384"></A>keyword
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that tells you if an object is an instance of a particular type. It returns a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>boolean
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">so
you use it in the form of a question, like this:
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#0000ff">if</font>(x <font color="#0000ff">instanceof</font> Dog)
  ((Dog)x).bark(); </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
above 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>if</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
statement checks to see if the object 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>x</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
belongs to the class 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Dog</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>before</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
casting 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>x</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Dog</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It&#8217;s important to use 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
before a downcast when you don&#8217;t have other information that tells you
the type of the object; otherwise you&#8217;ll end up with a <A NAME="Index1385"></A><A NAME="Index1386"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ClassCastException</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Ordinarily,
you might be hunting for one type (triangles to turn purple, for example), but
the following program shows how to tally 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>all</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of the objects using 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: PetCount.java</font>
<font color="#009900">// Using instanceof</font>
<font color="#0000ff">package</font> c11.petcount;
<font color="#0000ff">import</font> java.util.*;

<font color="#0000ff">class</font> Pet {}
<font color="#0000ff">class</font> Dog <font color="#0000ff">extends</font> Pet {}
<font color="#0000ff">class</font> Pug <font color="#0000ff">extends</font> Dog {}
<font color="#0000ff">class</font> Cat <font color="#0000ff">extends</font> Pet {}
<font color="#0000ff">class</font> Rodent <font color="#0000ff">extends</font> Pet {}
<font color="#0000ff">class</font> Gerbil <font color="#0000ff">extends</font> Rodent {}
<font color="#0000ff">class</font> Hamster <font color="#0000ff">extends</font> Rodent {}

<font color="#0000ff">class</font> Counter { <font color="#0000ff">int</font> i; }

<font color="#0000ff">public</font> <font color="#0000ff">class</font> PetCount {
  <font color="#0000ff">static</font> String[] typenames = {
    "Pet", "Dog", "Pug", "Cat",
    "Rodent", "Gerbil", "Hamster",
  };
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Vector pets = <font color="#0000ff">new</font> Vector();
    <font color="#0000ff">try</font> {
      Class[] petTypes = {
        Class.forName("c11.petcount.Dog"),
        Class.forName("c11.petcount.Pug"),
        Class.forName("c11.petcount.Cat"),
        Class.forName("c11.petcount.Rodent"),
        Class.forName("c11.petcount.Gerbil"),
        Class.forName("c11.petcount.Hamster"),
      };
      <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; 15; i++)
        pets.addElement(
          petTypes[
            (<font color="#0000ff">int</font>)(Math.random()*petTypes.length)]
            .newInstance());
    } <font color="#0000ff">catch</font>(InstantiationException e) {}
      <font color="#0000ff">catch</font>(IllegalAccessException e) {}
      <font color="#0000ff">catch</font>(ClassNotFoundException e) {}
    Hashtable h = <font color="#0000ff">new</font> Hashtable();
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; typenames.length; i++)
      h.put(typenames[i], <font color="#0000ff">new</font> Counter());
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; pets.size(); i++) {
      Object o = pets.elementAt(i);
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Pet)
        ((Counter)h.get("Pet")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Dog)
        ((Counter)h.get("Dog")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Pug)
        ((Counter)h.get("Pug")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Cat)
        ((Counter)h.get("Cat")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Rodent)
        ((Counter)h.get("Rodent")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Gerbil)
        ((Counter)h.get("Gerbil")).i++;
      <font color="#0000ff">if</font>(o <font color="#0000ff">instanceof</font> Hamster)
        ((Counter)h.get("Hamster")).i++;
    }
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; pets.size(); i++)
      System.out.println(
        pets.elementAt(i).getClass().toString());
    <font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i &lt; typenames.length; i++)
      System.out.println(
        typenames[i] + " quantity: " +
        ((Counter)h.get(typenames[i])).i);
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><a name="_Toc305593310"></a><a name="_Toc305628782"></a><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There&#8217;s
a rather narrow restriction on 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">in
Java 1.0<A NAME="Index1387"></A>:
You can compare it to a named type only, and not to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object. In the example above you might feel that it&#8217;s tedious to write
out all of those 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
expressions, and you&#8217;re right. But in Java 1.0 there is no way to
cleverly automate it by creating a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Class</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
objects and comparing it to those instead. This isn&#8217;t as great a
restriction as you might think, because you&#8217;ll eventually understand that
your design is probably flawed if you end up writing a lot of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>instanceof</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
expressions.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Of
course this example is contrived &#8211; you&#8217;d probably put a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
data member in each type and increment it in the constructor to keep track of
the counts. You would do something like that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>if</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you had control of the source code for the class and could change it. Since
this is not always the case, RTTI can come in handy.
</FONT><P></DIV>
<A NAME="Heading357"></A><H4 ALIGN=LEFT>
Using
class literals
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It&#8217;s
interesting to see how the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>PetCount.java</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -