- final参数
Java允许你在参数列表以声明的方式将参数指明为final. 这意味着你无法在方法中更改参数引用所指向的对象.
看例子:
- //: FinalArguments.java
- class Gizmo {
- public void spin() {}
- }
- public class FinalArguments {
- void with (final Gizmo g) {
- //! g = new Gizmo(); //错误:g不能被更改
- }
- void without(Gizmo g) {
- g = new Gizmo(); //没问题
- g.spin();
- }
- //void f(final int i) {i++;} //错误:i不能更改
- //final是只读的
- int g(final int i) {return i + 1;}
- public static void main(String[] args) {
- FinalArguments bf = new FinalArguments();
- bf.without(null);
- bf.with(null);
- }
- }
方法f()和g()展示了当原始类型的参数被指明为final时所出现的结果:你可以读参数,却无法修改参数. 这一特性看起来仅有微不足道的用处,而且你可能还用不到!呵呵!
来看下一种使用final的情况:
- final方法
1. 将方法锁定,以防任何继承类修改它的意义,这是出于设计的考虑: 你想要确保在继承中方法行为保持不变,并且不会被重载.
2. 效率. 如果你将一个方法指明为final,就是同意编译器将对该方法的所有调用都转为内嵌(inline)调用. 当编译器发现一个final方法调用命令时,它会根据自己的谨慎判断,跳过插入程序代码的正常方法而执行方法调用机制(将参数压入栈,跳至方法代码处并执行,然后跳回并清除栈中的参数,并处理返回值.), 并且以方法体中的实际代码的副本来代替方法调用.这将消除方法调用的开销. 当然,如果一个方法很大,你的程序代码就会膨胀,你可能看不到内嵌带来的任何性能提高,因此,你所取得的性能提高会因为花费于方法内的时间总量而被缩减. 这意味着Java编译器能够观察到这些情况并明智地抉择是否对final方法执行内嵌动作. 然而,最好是让编译器和JVM仅在你明确表示要阻止重载时,在处理效率事项,并将方法指明为final.
final和private
类中所有的private方法都被隐含是final的. 由于你无法取用private方法,所以你无法重载之.你可以对private方法增加final修饰符,但这并不能给该方法增加任何额外的意义
这个问题会造成混淆. 因为如果你试图重载一个private方法(隐含是final的),看起来是奏效的,而且编译器不会给出错误信息.
比如:
- //: FinalOverridingIllusion.java
- class WithFinals {
- private final void f() {
- System.out.println("WithFinals.f()");
- }
- private void g() {
- System.out.println("WithFinals.g()");
- }
- }
- class OverridingPrivate extends WithFinals {
- private final void f() {
- System.out.println("OverridingPrivate.f()");
- }
- private void g() {
- System.out.println("OverridingPrivate.g()");
- }
- }
- class OverridingPrivate2 extends OverridingPrivate {
- public final void f() {
- System.out.println("OverridingPrivate2.f()");
- }
- public void g() {
- System.out.println("OverridingPrivate2.g()");
- }
- }
- public class FinalOverridingIllusion {
- public static void main(String[] args) {
- OverridingPrivate2 op2 = new OverridingPrivate2();
- op2.f();
- op2.g();
- //向上转型一下
- OverridingPrivate op = op2; //基类引用指向了导出类对
- //象,实现向上转型
- //但是你不能调用op的方法
- //! op.f();
- //! op.g();
- WithFinals wf = op2; //向上转型至WithFinals类型,那
- //么对象wf就只看到了op2的WithFinals部分
- //! wf.f();
- //! wf.g();
- }
- }
<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
- final 类
当你将某各类的整体定义为final时(通过将关键字至于它的定义之前),你就声明了你打算继承该类,而且不允许别人这么做. 换句话说,出于某种考虑,你对该类的设计用不需要做任何变动,或者出于安全的考虑,你不希望它有子类.
例子:
- //! Jurassic.java
- class SmallBrain {}
- final class Dinosaur {
- int i = 7;
- int j = 1;
- SmallBrain x = new SmallBrain();
- void f() {}
- }
- //!class Further extends Dinosaur {}
- //错误:Dinosaur是final的,所以不能继承,但是其类成员可以改变
- public class Jurassic {
- public static void main(String[] args) {
- Dinosaur n = new Dinosaur();
- n.f();
- n.i = 40;
- n.j++;
- }
- }
--------------------未完待续---------------------