还是TIJ里把final解释得最彻底

以前我是这样理解final的:

final表示最终的,它可以修饰变量,方法和类。当它修饰变量的时候,这个变量不能再被与修改(注:错误的,至少不全);当它修饰方法时,该方法不能被override(重写);当它修饰类时,该类不能再派生出子类。

回头看了TIJ, 才知道自己的理解其实很片面,或者很肤浅,下面是TIJ里对final阐述的总结:


final表示“这样东西是不允许改动的”的意思。它可以修饰数据,方法,以及类。

[b]final数据[/b]

对primitive来说,final会将这个值定义成常量,在定义时赋值;既是static又是final的数据成员会只占据一段内存,并且不可修改。
对reference来说,final的意思则是这个reference是常量,初始化的时候,一旦将reference连接到某个对象,那么它就再也不能指别的对象了,但这个对象本身是可以修改的,Java没有提供将某个对象当作常量的方法。

[b]final 方法[/b]
禁止派生类修改该方法!

[b]final和private[/b]
Private方法已经隐含有final的意思,因为外部是不能访问private的,也就不存在覆写它。

[b]final类[/b]
出于类的设计考虑,它再也不需要作修改了;或者从安全角度出发,不希望它再派生出子类。
final类的数据可以是final的,也可以不是final的,这由自己决定;对于它的方法,由于final类禁止了继承,覆写方法已经不可能,所以所有的方法都隐含地变成final的了!

下面是TIJ4里关于final的一些示例:


/*************************** "final" 修饰参数示例/***************************/

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++; }
// 只能读取primitive类型的常量,不能修改

int g(final int i) {return i + 1; }

public static void main(String[] args)
{
FinalArguments bf = new FinalArguments();
bf.without(null);
bf.with(null);
}
} // /:~

/*************************** final成员变量的示例 ***************************/
import java.util.*;
import static net.mindview.util.Print.*;

class Value
{
int i; // 包访问限制
public Value(int i) { this.i = i; }
}

public class FinalData
{
private static Random rand = new Random(47);
private String id;

public FinalData(String id) { this.id = id; }

// 编译时常量
private final int valueOne = 9;
private static final int VALUE_TWO = 99;

// 典型的公共访问常量
public static final int VALUE_THREE = 39;

// 非编译时常量
private final int i4 = rand.nextInt(20);
static final int INT_5 = rand.nextInt(20);

// 对象引用常量
private Value v1 = new Value(11);
private final Value v2 = new Value(22);
private static final Value VAL_3 = new Value(33);

// 数组
private final int[] a = { 1, 2, 3, 4, 5, 6 };

//重写toString()方法
public String toString()
{
return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
}

public static void main(String[] args)
{
FinalData fd1 = new FinalData("fd1");
// ! fd1.valueOne++; // Error: can't change value
fd1.v2.i++; // Object isn't constant!
fd1.v1 = new Value(9); // OK -- not final
for (int i = 0; i < fd1.a.length; i++)
fd1.a[i]++; // Object isn't constant!
// ! fd1.v2 = new Value(0); // Error: Can't
// ! fd1.VAL_3 = new Value(1); // change reference
// ! fd1.a = new int[3];
print(fd1);
print("Creating new FinalData");
FinalData fd2 = new FinalData("fd2");
print(fd1);
print(fd2);
}
}/* Output:
fd1: i4 = 15, INT_5 = 18
Creating new FinalData
fd1: i4 = 15, INT_5 = 18
fd2: i4 = 13, INT_5 = 18
*///:~

/*************************** final,private的示例 ***************************/

class WithFinals
{
// 虽然加上了final,但效果和只有private一样,private+final是无意义的
private final void f()
{
print("WithFinals.f()");
}
// private在其它类中本身就看不见,也就无法重写,相当于隐含了final
private void g()
{
print("WithFinals.g()");
}
}

class OverridingPrivate extends WithFinals
{
private final void f()
{
print("OverridingPrivate.f()");
}
private void g()
{
print("OverridingPrivate.g()");
}
}

class OverridingPrivate2 extends OverridingPrivate
{
public final void f()
{
print("OverridingPrivate2.f()");
}
public void g()
{
print("OverridingPrivate2.g()");
}
}

public class FinalOverridingIllusion
{
public static void main(String[] args)
{
OverridingPrivate2 op2 = new OverridingPrivate2();
op2.f();
op2.g();
// You can upcast:
OverridingPrivate op = op2;
// But you can't call the methods:
// ! op.f();
// ! op.g();
// Same here:
WithFinals wf = op2;
// ! wf.f();
// ! wf.g();
}
}
/* Output:
OverridingPrivate2.f()
OverridingPrivate2.g()
*///:~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值