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

📄 tij0071.html

📁 学习java的经典书籍
💻 HTML
📖 第 1 页 / 共 3 页
字号:
code to perform the method call mechanism (push arguments on the stack, hop
over to the method code and execute it, hop back and clean off the stack
arguments, and deal with the return value) and instead replace the method call
with a copy of the actual code in the method body. This eliminates the overhead
of the method call. Of course, if a method is big, then your code begins to
bloat and you probably won’t see any performance gains from inlining
since any improvements will be dwarfed by the amount of time spent inside the
method. It is implied that the Java compiler is able to detect these situations
and choose wisely whether to inline a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method. However, it&#8217;s better to not trust that the compiler is able to do
this and make a method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
only if it&#8217;s quite small or if you want to explicitly prevent overriding.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Any
<A NAME="Index530"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods in a class are implicitly 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Because you can&#8217;t access a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">method,
you can&#8217;t override it (the compiler gives an error message if you try).
You can add the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
specifier to a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>private</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method but it doesn&#8217;t give that method any extra meaning.
</FONT><a name="_Toc375545320"></a><a name="_Toc408018523"></a><P></DIV>
<A NAME="Heading201"></A><H3 ALIGN=LEFT>
Final
classes
<P><A NAME="Index531"></A><A NAME="Index532"></A></H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you say that an entire class is 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(by preceding its definition with the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
keyword), you state that you don&#8217;t want to inherit from this class or
allow anyone else to do so. In other words, for some reason the design of your
class is such that there is never a need to make any changes, or for safety or
security reasons you don&#8217;t want subclassing. Alternatively, you might be
dealing with an efficiency issue and you want to make sure that any activity
involved with objects of this class is as efficient as possible.
</FONT><P></DIV>

<font color="#990000"><PRE><font color="#009900">//: Jurassic.java</font>
<font color="#009900">// Making an entire class final</font>

<font color="#0000ff">class</font> SmallBrain {}

<font color="#0000ff">final</font> <font color="#0000ff">class</font> Dinosaur {
  <font color="#0000ff">int</font> i = 7;
  <font color="#0000ff">int</font> j = 1;
  SmallBrain x = <font color="#0000ff">new</font> SmallBrain();
  <font color="#0000ff">void</font> f() {}
}

<font color="#009900">//! class Further extends Dinosaur {}</font>
<font color="#009900">// error: Cannot extend final class 'Dinosaur'</font>

<font color="#0000ff">public</font> <font color="#0000ff">class</font> Jurassic {
  <font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
    Dinosaur n = <font color="#0000ff">new</font> Dinosaur();
    n.f();
    n.i = 40;
    n.j++;
  }
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Note
that the data members can be 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or not, as you choose. The same rules apply to 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for data members regardless of whether the class is defined as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Defining the class as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
simply prevents inheritance &#8211; nothing more. However, because it prevents <A NAME="Index533"></A>inheritance
all methods in a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class are implicitly 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
since there&#8217;s no way to override them. So the compiler has the same
efficiency options as it does if you explicitly declare a method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</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">You
can add the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
specifier to a method in a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class, but it doesn&#8217;t add any meaning.
</FONT><a name="_Toc375545321"></a><a name="_Toc408018524"></a><P></DIV>
<A NAME="Heading202"></A><H3 ALIGN=LEFT>
Final
caution
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It
can seem to be sensible to make a method 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
while you&#8217;re designing a class. You might feel that <A NAME="Index534"></A><A NAME="Index535"></A><A NAME="Index536"></A>efficiency
is very important when using your class and that no one could possibly want to
override your methods anyway. Sometimes this is true.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">But
be careful with your assumptions. In general, it&#8217;s difficult to
anticipate how a class can be reused, especially a general-purpose class. If
you define a method as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
you might prevent the possibility of reusing your class through inheritance in
some other programmer&#8217;s project simply because you couldn&#8217;t imagine
it being used that way.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
standard Java library is a good example of this. In particular, the 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
class is commonly used and might be even more useful if, in the name of
efficiency, all the methods hadn&#8217;t been made 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
It&#8217;s easily conceivable that you might want to inherit and override with
such a fundamentally useful class, but the designers somehow decided this
wasn&#8217;t appropriate. This is ironic for two reasons. First, 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Stack
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">is
inherited from 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which says that a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Stack
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>is</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
a 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which isn&#8217;t really true. Second, many of the most important methods of 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
such as 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>addElement(&#160;)
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>elementAt(&#160;)</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>synchronized</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which as you will see in Chapter 14 incurs a significant performance overhead
that probably wipes out any gains provided by 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
This lends credence to the theory that programmers are consistently bad at
guessing where optimizations should occur. It&#8217;s just too bad that such a
clumsy design made it into the standard library where we must all cope with it.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">It&#8217;s
also interesting to note that 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
another important standard library class, does 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
have any 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods. As mentioned elsewhere in this book, it&#8217;s quite obvious that
some classes were designed by completely different people than others. (Notice
the brevity of the method names in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Hashtable</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
compared to those in 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Vector</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.)
This is precisely the sort of thing that should 
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>not</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
be obvious to consumers of a class library. When things are inconsistent it
just makes more work for the user. Yet another paean to the value of design and
code walkthroughs.
</FONT><a name="_Toc375545322"></a><a name="_Toc408018525"></a><P></DIV>

<div align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0070.html">Prev</a> | <a href="tij0072.html">Next</a>
</div>
</body></html>

⌨️ 快捷键说明

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