Content deleted Content added
Tuankiet65 (talk | contribs) mNo edit summary |
m Task 70: Update syntaxhighlight tags - remove use of deprecated <source> tags |
||
Line 8:
Example:
<
public final class MyFinalClass {...}
public class ThisIsWrong extends MyFinalClass {...} // forbidden
</syntaxhighlight>
==Final methods==
Line 19:
Example:
<
public class Base
{
Line 37:
public static void m4() {...} // forbidden
}
</syntaxhighlight>
A common misconception is that declaring a method as <code>final</code> improves efficiency by allowing the compiler to directly insert the method wherever it is called (see [[inline expansion]]). Because the method is loaded at [[run time (program lifecycle phase)|runtime]], compilers are unable to do this. Only the runtime environment and [[Just-in-time compilation|JIT]] compiler know exactly which classes have been loaded, and so only they are able to make decisions about when to inline, whether or not the method is final.<ref>[http://www.ibm.com/developerworks/java/library/j-jtp1029.html Java theory and practice: Is that your final answer?]</ref>
Line 49:
Example:
<
public class Sphere {
Line 69:
[...]
}
</syntaxhighlight>
Any attempt to reassign <code>radius</code>, <code>xPos</code>, <code>yPos</code>, or <code>zPos</code> will result in a compile error. In fact, even if the constructor doesn't set a final variable, attempting to set it outside the constructor will result in a compilation error.
Line 75:
To illustrate that finality doesn't guarantee immutability: suppose we replace the three position variables with a single one:
<
public final Position pos;
</syntaxhighlight>
where <code>pos</code> is an object with three properties <code>pos.x</code>, <code>pos.y</code> and <code>pos.z</code>. Then <code>pos</code> cannot be assigned to, but the three properties can, unless they are final themselves.
Line 85:
Though it appears to violate the <code>final</code> principle, the following is a legal statement:
<
for (final SomeObject obj : someList) {
// do something with obj
}
</syntaxhighlight>
Since the obj variable goes out of scope with each iteration of the loop, it is actually redeclared each iteration, allowing the same token (i.e. <code>obj</code>) to be used to represent multiple variables.<ref>{{cite web|url=https://www.cs.cmu.edu/~pattis/15-1XX/15-200/lectures/morejava/lecture.html|title=More Java|last=Pattis|first=Richard E.|work=Advanced Programming/Practicum 15–200|publisher=School of Computer Science [[Carnegie Mellon University]]|accessdate=23 July 2010}}</ref>
Line 98:
If the above construction is violated by having an object in the tree that is not immutable, the expectation does not hold that anything reachable via the final variable is constant. For example, the following code defines a coordinate system whose origin should always be at (0, 0). The origin is implemented using a <code>java.awt.Point</code> though, and this class defines its fields as public and modifiable. This means that even when reaching the <code>origin</code> object over an access path with only final variables, that object can still be modified, as the below example code demonstrates.
<
import java.awt.Point;
Line 117:
}
}
</syntaxhighlight>
The reason for this is that declaring a variable final only means that this variable will point to the same object at any time. The object that the variable points to is not influenced by that final variable though. In the above example, the origin's x and y coordinates can be freely modified.
Line 126:
When an anonymous [[inner class]] is defined within the body of a method, all variables declared <code>final</code> in the scope of that method are accessible from within the inner class. For scalar values, once it has been assigned, the value of the <code>final</code> variable cannot change. For object values, the reference cannot change. This allows the Java compiler to "capture" the value of the variable at run-time and store a copy as a field in the inner class. Once the outer method has terminated and its [[call stack|stack frame]] has been removed, the original variable is gone but the inner class's private copy persists in the class's own memory.
<
import javax.swing.*;
Line 147:
}
}
</syntaxhighlight>
===Blank final===
The '''blank final''', which was introduced in Java 1.1, is a final variable whose declaration lacks an initializer.<ref>{{cite book|last=Flanagan|first=David|title=Java in a Nutshell|url=https://archive.org/details/javainnutshelld100flan|edition=2nd|date=May 1997|publisher=O'Reilly|isbn=1-56592-262-X|chapter=Chapter 5 Inner Classes and Other New Language Features:5.6 Other New Features of Java 1.1|url-access=registration}}</ref><ref>{{cite web|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4|title=Chapter 4. Types, Values, and Variables|year=2015|work=The Java® Language Specification (Java SE 8 Edition)|publisher=Oracle America, Inc.|access-date=23 Feb 2015}}</ref> Previous to Java 1.1, a final variable was required to have an initializer. A blank final, by definition of "final", can only be assigned once. i.e. it must be unassigned when an assignment occurs. In order to do this, a Java compiler runs a flow analysis to ensure that, for every assignment to a blank final variable, the variable is definitely unassigned before the assignment; otherwise a compile-time error occurs.<ref name="define_assignment">{{cite web|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-16.html|title=Definite Assignment|year=2015|work=The Java® Language Specification (Java SE 8 Edition)|publisher=Oracle America, Inc.|access-date=29 Oct 2016}}</ref>
<
final boolean hasTwoDigits;
if (number >= 10 && number < 100) {
Line 160:
hasTwoDigits = true; // compile-error because the final variable might already be assigned.
}
</syntaxhighlight>
In addition, a blank final also has to be definitely assigned before being accessed. <ref name="define_assignment" />
<
final boolean isEven;
Line 172:
System.out.println(isEven); // compile-error because the variable was not assigned in the else-case.
</syntaxhighlight>
Note though that a non-final local variable also needs to be definitely assigned before being accessed. <ref name="define_assignment" />
<
boolean isEven; // *not* final
Line 185:
System.out.println(isEven); // Same compile-error because the non-final variable was not assigned in the else-case.
</syntaxhighlight>
==C/C++ analog of final variables==
|