final修饰的情况一共有三种情况:
- final修饰属性:该属性叫做常量(不能改变)
- final修饰类:该类完美,不能被继承
- final修饰方法:该方法完美,不能被重写
下面就这三中情况分别说明:
-
fianl修饰域的情况
- 当一个域被修饰成final时,必须在域声明处或构造器(或构造块)中进行初始化,这也是final域总是在使用前被初始化了的原因。
- 当一个引用对象被final 修饰是指它的所指向的对象不能被改变,而其对象的属性可以被改变,其指向数组也是一样。
- static final强调的是它只是这一封,不会随着对象的创建而改变
下面来看如下代码:
import java.util.Random;
/**测试fianl修饰域
* @author QuLei
*
*/
public class FinalData {
private static Random rand = new Random(47);
private String id;
public FinalData(String id) {
super();
this.id = id;
}
//定义一个final修饰的域
private final int valueOne = 9;
//被static final修饰的域
private static final int VALUE_TWO = 99;
//前面的修饰是public 是一种典型的对常量定义的方式
public static final int VALUE_THREE = 39;
//测试final 与 static final修饰的区别
private final int i4 = rand.nextInt(20);
private static final int INT_5 = rand.nextInt(20);
//final修饰引用类型
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};
public String toString() {
return id +":"+"i4 = "+i4 + ",INT_5="+ INT_5;
}
public static void main(String[] args) {
FinalData fd1 = new FinalData("fd1");
System.out.println(fd1.valueOne);
fd1.v2.i ++;
fd1.v1 = new Value(9);
for(int i =0 ;i < fd1.a.length;i++) {
fd1.a[i]++;
//! fd1.v2 = new Value(0); Error;cant't
//!fd1.VAL_3 = new Value(1); chang reference
//fd1.a = new int[3];
System.out.println(fd1);
System.out.println("Creating new FinalData");
FinalData fd2 = new FinalData("fd2");
System.out.println(fd1);
System.out.println(fd2);
}
}
}
/**一个普通的类用来测试final 修饰引用
* @author QuLei
*
*/
class Value{
int i ;
public Value(int i) {
super();
this.i = i;
}
}
/**测试static final 和 final修饰域的区别
* @author QuLei
*
*/
class Test11 {
public static final int i ;
public final int j ;
static {
i = 10;
}
public Test11(int j) {
super();
this.j = j;
}
}
这段代码的输出结果为:
9
fd1:i4 = 15,INT_5=18
Creating new FinalData
fd1:i4 = 15,INT_5=18
fd2:i4 = 13,INT_5=18
fd1:i4 = 15,INT_5=18
*///:~
final修饰参数的情况:
Java中允许在参数列表中以声明的方式将参数指明为final。这意味着你无法在方法中更改该参数引用所指向的对象。如下面的代码:
-
class Gizmo{ public void spin() {} } public class FinalArguments { void with(final Gizmo g) { //g = new Gizmo(); //Illegal -- g is final } void without(Gizmo g) { g = new Gizmo(); //ok g is not final g.spin(); } void f(final int i) { //i++; //Cant't change } //you can only read from a final 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修饰方法:final修饰方法该方法不能被子类重写(覆盖@Override),private 修饰的方法隐含有final修饰
- fianl 修饰类:final修饰类该类不能被继承