Java 51个关键字——关键字final

目录

一、前言

二、final修饰的变量为常量

2.1 基本类型与引用类型

2.1.1 基本类型(byte short int long float double boolean char)

2.1.2 引用类型 (类、接口、数组)

2.2 初始化时机

2.2.1 final变量定义时初始化 

2.2.2 final变量构造函数中初始化(空白final)

三、final修饰的类不可继承

四、final修饰的方法不可重写

五、private与final对比

六、小结


一、前言

     Java语言中final是一个关键字(key words),其表示的三个含义:final修饰的变量是常量,final修饰的类不可继承,final修饰的方法不可重写。

final关键字三个特性:final修饰的变量为常量、final修饰的类不可继承、final修饰的方法不可重写,详见第二、三、四部分。

二、final修饰的变量为常量

2.1 基本类型与引用类型

对于final修饰的变量,应该对基本类型和引用类型分开讨论:

2.1.1 基本类型(byte short int long float double boolean char)

基本类型为栈内存(-128~127情况下),一旦被final关键字修饰,其变量属性变为只读,不再进行写操作,否则编译报错。

2.1.2 引用类型 (类、接口、数组)

引用类型为堆内存,一旦被final关键字修饰,则引用不再改变,但是引用所指向的对象是可以被修改的,Java语言并未提供任何方式使用对象恒定不变。示意代码如下:

public class FinalData {
private final Value value=new Value(22);
public static void main(String[] args) {
	FinalData finalData=new FinalData();
	
	//finalData.value=new Value(33);   //编译报错    value为final类型   
	finalData.value.i++; // 编译通过  value所指向的对象可以修改 
}
}
class Value{
	int i;
	public Value(int i){
		this.i=i;
	}
}

2.2 初始化时机

2.2.1 final变量定义时初始化 

final变量定义时初始化常见,定义时直接赋值即可,不再赘言。              

2.2.2 final变量构造函数中初始化(空白final)

因为被final修饰的变量一定要在使用前被初始化,所以如果没在定义操作,一定在构造函数中初始化,这种情况称为空白final。示例代码如下:

public class FinalData {
	private final int i;//基本类型示意
private final Value value;//引用类型示意
public FinalData(){ //  无参构造函数    空白final
	i=1;
	value=new Value(1);
}
public FinalData(int x){//有参构造函数  空白final
	i=x;
	value=new Value(x);
}

public static void main(String[] args) {
	new FinalData();
	new FinalData(22);
 
}
}
class Value{
	int i;
	public Value(int i){
		this.i=i;
	}
}

三、final修饰的类不可继承

类使用final关键字修饰之后,该类不可被继承,可以起到保护该类的作用。实例代码如下:

final class FinalFatherClass{
	
}
class SonClass extends FinalFatherClass{  //编译报错   final类不允许继承
	
}

四、final修饰的方法不可重写

class FinalFatherClass{
	final void f(){
		System.out.println("FinalFatherClass f()");
	}
}
class SonClass extends FinalFatherClass{  
	final void f(){//编译报错    
// 子类中某一方法的方法签名(方法名+形参列表)与父类相同,即可认为子类中该方法重写父类方法
//因final方法不可被重写,顾此处编译报错
		System.out.println("SonClass f()");
	}
}

值得注意的是,子类虽不能重写父类final函数,但是可以继承父类final函数,示意代码如下:

public class TestFinal {
public static void main(String[] args){
	FinalFatherClass son=new SonClass();
	son.f();    //打印  FinalFatherClass f()
	//因为子类未重写父类final函数,也不能重新父类final函数    
	//但子类可以继承父类final函数,所以调用父类 f()  打印  FinalFatherClass f() 

}
}
class FinalFatherClass{
	final void f(){
		System.out.println("FinalFatherClass f()");
	}
}
class SonClass extends FinalFatherClass{ 
	
}

从上面可以看到,final修饰的方法在特定的访问权限下可以被继承。

这是因为,方法是否被final修饰与方法的访问权限是两回事,没有任何关系,被final修饰的方法和未被final修饰的方法都可以自由的指定访问权限。 

我们有兴趣去谈论final关键字和访问权限关键字在修饰方法的过程的起到的作用, 如下表(声明:final和访问权限是两个独立的概念,没有任何比较意义,所有本表仅方便读者理解,不可作为正统知识) :  

  protect关键字 final关键字 private关键字
是否可以继承
是否可以重写
小结 private<final<protect  (仅适用于方法)

从表中可以看到,protect修饰的方法在子类中可见,所有可以被子类继承,亦可以被子类重写;

final修饰的方法可以被子类继承,但不可被子类重写(这里final方法的访问权限为默认的default、protected、public均可,只要保证子类可见即可);

private修饰的方法由于仅本类可见,故不能被子类继承,亦不能被子类重写;

五、private与final对比

实际上,Java语言中,所有被private关键字修饰的方法都隐式的被final关键字修饰,(正如上表所示,private实现了final方法不可重写的功能,并附加不可继承功能。)(再次声明:final和访问权限是两个独立的概念,没有任何比较意义,所有上表仅方便读者理解,不可作为正统知识)可以对private方法添加final关键字,但是这种做法没有任何意义。代码示例如下:

public class TestFinal {
public static void main(String[] args){
	FinalFatherClass fatherClass=new FinalFatherClass();

SonClass sonClass=new SonClass();
//fatherClass.f();   //f() 为final方法  被private修饰后 仅本类可见  所有不能到TestFinal类中调用
//sonClass.f();

//fatherClass.g();   //g() 虽然不是final方法  但被private修饰后 也是仅本类可见  所有不能到TestFinal类中调用
//sonClass.g();

//小结:java中,private方法已经隐式的包含final关键字     所以final关键字有无并不重要
}
}
class FinalFatherClass{
	private final void f(){
		System.out.println("FinalFatherClass f()");
	}
	private void g(){
		System.out.println("FinalFatherClass g()");
	}
}
class SonClass extends FinalFatherClass{ 
	private final void f(){
		System.out.println("SonClass f()");
	}
	private void g(){
		System.out.println("SonClass g()");
	}
}

六、小结

       本文介绍final关键字,分别介绍了:

       final关键字修饰变量,将变量变成常量,一般用来设置全局变量;

       final关键字修饰类,将类变为不可以被继承的类;

       final关键字修饰方法,将方法变为不可被重写的方法(但是可以被继承,只要是在该方法的访问控制权限允许的情况下);

       最后讨论final关键字和访问控制权限的关系,对比了private和final,从某种意义上来说,final是介于protected和private之间的一种访问权限(虽然不准确,但是至少可以这样理解)。

天天打码,天天进步!

发布了177 篇原创文章 · 获赞 31 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_36963950/article/details/100972019