final关键字
“这是无法改变的。”
final数据
被final修饰的数据一旦被初始化后就不得被改变。基本类型运用final时,数值恒定不变。对象/数组(数组是一种特殊的引用)运用final时,引用恒定不变,可以改变对象的值。
引用存在堆栈中,对象存在堆中。final修饰的是堆栈中的对象的引用,而不是堆中的对象。final修饰的引用无法指向堆中另外一个地址的对象,但是可有修改原对象的值,因为引用不会变化。
import java.util.Arrays;
class Value{
int v;
public Value(int v) {
super();
this.v = v;
}
@Override
public String toString() {
return "Value [v=" + v + "]";
}
}
public class FinalData {
private int id;
private final char finalValue='f';
private static final int FINAL_AND_STATIC_VALUE=20;
private final Value finalObject=new Value(30);
private final int[] finalArray={1,2,3,4,5};
public FinalData(int id) {
super();
this.id = id;
}
void functionWithFinalArgs(final Value value,final int i){
//final基本类型参数无法修改值,对象参数无法修改引用
// value=new Value(0);
// i=0;
}
public static void main(String[] args){
FinalData finalData=new FinalData(1);
//final基本类型数值无法更改,编译器报错
// finalData.FINAL_AND_STATIC_VALUE=30;
// finalData.finalValue='a';
//final对象/数组 引用无法更改,编译器报错
Value newValue=new Value(10);
// finalData.finalObject=newValue;
int[] newArray={1,2,3};
// finalData.finalArray=newArray;
//final对象/数组 对象值可以修改
finalData.finalObject.v=10;
System.out.println(finalData.finalObject);
for(int i=0;i<finalData.finalArray.length;i++){
finalData.finalArray[i]++;
}
System.out.println(Arrays.toString(finalData.finalArray));
}
}
/*Output:
Value [v=10]
[2, 3, 4, 5, 6]
*/
空白final
被声明final但未给定初值的域。需要在使用之前进行初始化,一般在构造方法中进行初始化。
public class BlankFinalData {
private final int value;
// {
// value=10;
// }
public BlankFinalData(int value) {
super();
this.value = value;
}
public BlankFinalData() {
super();
this.value=0;
}
public static void main(String[] args){
BlankFinalData blankFinalData = new BlankFinalData();
System.out.println(blankFinalData.value);
blankFinalData=new BlankFinalData(1);
System.out.println(blankFinalData.value);
}
}
/*
* Output
* 0
* 1
*/
可以看到注释掉了构造代码块,构造代码块与构造函数不能同时对final参数修改。因为构造代码块优先于构造函数执行,构造代码块执行时参数已经被初始化,构造函数中就不能再次修改。
空白final为final数据提供了更大的灵活性,该类的不同对象final数据的值可能调用不同构造方法而拥有不同值,但值都不能被再次改变。
final数据恒定不变有两个用途:
1.一个永不改变的编译常量(在声明是就初始化)
2.一个在运行时被初始化的值,而你不希望它被改变(空白final)
final方法
final方法不可以被子类重写。
package final_modifier;
public class FinalMethod {
final void finalMethod(){
}
private void privateMethod(){
System.out.println("father method");
}
}
class ChildClass extends FinalMethod{
//final方法不能被重写
// @Override
// void finalMethod(){
// System.out.println("change something");
// }
//private方法无法重写
// @Override
private void privateMethod(){
System.out.println("child method");
}
}
private方法与final方法
private方法与final方法都不能被重写。
更确切的说private方法其实跟子类一点关系没有,private只属于父类,不会被继承。
上例中试图为子类的与父类相同的private方法加上override注解时编译器就会报错,因为并没有方法被重写。
final类
final类不可以被继承。被final修饰的类不能被abstract修饰,final类不能被继承,abstract类需要被继承实现。
欢迎批评指正^ ^