📄 tij0071.html
字号:
presumably optimized out of existence.) The difference is shown in the output
from one run:
</FONT><P></DIV>
<font color="#990000"><PRE>fd1: i4 = 15, i5 = 9
Creating <font color="#0000ff">new</font> FinalData
fd1: i4 = 15, i5 = 9
fd2: i4 = 10, i5 = 9 </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Note
that the values of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>i4</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fd1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>fd2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
are unique, but the value for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>i5</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is not changed by creating the second
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>FinalData</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object. That’s because it’s
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>static</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and is initialized once upon loading and not each time a new object is created.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
variables
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
through
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v4</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
demonstrate the meaning of a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle. As you can see in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
just because
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn’t mean that you can’t change its value. However, you cannot
re-bind
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>v2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to a new object, precisely because it’s
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
That’s what
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
means for a handle. You can also see the same meaning holds true for an array,
which is just another kind of handle. (There is know way that I know of to make
the array handles themselves
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.)
Making handles
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
seems less useful than making primitives
</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>
<A NAME="Heading198"></A><H4 ALIGN=LEFT>
Blank
finals
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Java
1.1<A NAME="Index520"></A>
allows the creation of <A NAME="Index521"></A><A NAME="Index522"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>blank
finals
</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which are fields that are declared as
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
but are not given an initialization value. In all cases, the blank final
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>must</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
be initialized before it is used, and the compiler ensures this. However, blank
finals provide much more flexibility in the use of 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 since, for example, a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
field inside a class can now be different for each object and yet it retains
its immutable quality. Here’s an example:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: BlankFinal.java</font>
<font color="#009900">// "Blank" final data members</font>
<font color="#0000ff">class</font> Poppet { }
<font color="#0000ff">class</font> BlankFinal {
<font color="#0000ff">final</font> <font color="#0000ff">int</font> i = 0; <font color="#009900">// Initialized final</font>
<font color="#0000ff">final</font> <font color="#0000ff">int</font> j; <font color="#009900">// Blank final</font>
<font color="#0000ff">final</font> Poppet p; <font color="#009900">// Blank final handle</font>
<font color="#009900">// Blank finals MUST be initialized</font>
<font color="#009900">// in the constructor:</font>
BlankFinal() {
j = 1; <font color="#009900">// Initialize blank final</font>
p = <font color="#0000ff">new</font> Poppet();
}
BlankFinal(<font color="#0000ff">int</font> x) {
j = x; <font color="#009900">// Initialize blank final</font>
p = <font color="#0000ff">new</font> Poppet();
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
BlankFinal bf = <font color="#0000ff">new</font> BlankFinal();
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You’re
forced to perform assignments to finals either with an expression at the point
of definition of the field or in every constructor. This way it’s
guaranteed that the final field is always initialized before use.
</FONT><P></DIV>
<A NAME="Heading199"></A><H4 ALIGN=LEFT>
Final
arguments
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Java
1.1<A NAME="Index523"></A>
allows you to make <A NAME="Index524"></A><A NAME="Index525"></A>arguments
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
by declaring them as such in the argument list. This means that inside the
method you cannot change what the argument handle points to:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: FinalArguments.java</font>
<font color="#009900">// Using "final" with method arguments</font>
<font color="#0000ff">class</font> Gizmo {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> spin() {}
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> FinalArguments {
<font color="#0000ff">void</font> with(<font color="#0000ff">final</font> Gizmo g) {
<font color="#009900">//! g = new Gizmo(); // Illegal -- g is final</font>
g.spin();
}
<font color="#0000ff">void</font> without(Gizmo g) {
g = <font color="#0000ff">new</font> Gizmo(); <font color="#009900">// OK -- g not final</font>
g.spin();
}
<font color="#009900">// void f(final int i) { i++; } // Can't change</font>
<font color="#009900">// You can only read from a final primitive:</font>
<font color="#0000ff">int</font> g(<font color="#0000ff">final</font> <font color="#0000ff">int</font> i) { <font color="#0000ff">return</font> i + 1; }
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
FinalArguments bf = <font color="#0000ff">new</font> FinalArguments();
bf.without(<font color="#0000ff">null</font>);
bf.with(<font color="#0000ff">null</font>);
}
} <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 you can still assign a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>null</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
handle to an argument that’s final without the compiler catching it, just
like you can with a non-final argument.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
methods
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>g( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
show what happens when primitive arguments are
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">:
you can only read the argument, but you can't change it.
</FONT><a name="_Toc375545319"></a><a name="_Toc408018522"></a><P></DIV>
<A NAME="Heading200"></A><H3 ALIGN=LEFT>
Final
methods
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">There
are two reasons for <A NAME="Index526"></A><A NAME="Index527"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods. The first is to put a “lock” on the method to prevent any
inheriting class from changing its meaning. This is done for design reasons
when you want to make sure that a method’s behavior is retained during
inheritance and cannot be overridden.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
second reason for
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>final</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
methods is efficiency. If you 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">,
you are allowing the compiler to turn any calls to that method into <A NAME="Index528"></A><A NAME="Index529"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>inline</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
calls. When the compiler sees 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 call it can (at its discretion) skip the normal approach of inserting
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -