Java中的final关键字

Java中的final关键字意思是“最终的”,“无法改变的”。

值得提的是:final类不能被继承,它没有子类

     final类中的方法默认是final的

                     final方法不能被子类重定义,但是可以被继承

                     final变量只能一次赋值,往后不可更改

                     final不能用来修饰构造方法

主要有5种:①final修饰普通变量 ②空白final数据成员 ③final修饰方法参数 ④final修饰方法 ⑤final修饰类


对于①:

对于基本的数据成员,final会将值变成一个常量。但是对于对象句柄(对象句柄,就是一个对象变量),final会将句柄变成一个常量,而且声明时的同时必须初始化。虽然对象句柄是常量,但是对象本身是可以修改的,且对象里的成员若没有final修饰,就不是常量,是可以改变的。

例如以下:

class Value{
	int i=1;
}
public class FinalData {
	final int i1=9;    
	static final int i2=99;   
	public static final int i3=39;
	
	final int i4=(int)(Math.random()*20);
	static final int i5=(int)(Math.random()*20);
	
	Value v1=new Value();
	final Value v2=new Value();
	
	// final Value v4;   此处错误!必须在类的初始化中完成对v4的初始化
	
	final int[]a={1,2,3,4,5,6};
	
	public void print(String id){
		System.out.println(id+":"+"i4="+i4+",i5="+i5);
	}
	public static void main(String[] args){
		FinalData fd1=new FinalData();
		// fd1.i1++;   此处错误!不能对常量进行加一
		fd1.v2.i++;    //这里是正确的,尽管v2是常量,但是v2里面的i不是常量,是可以进行改变的
		fd1.v1=new Value();   //这里是正确的,v1没有声明为final,可以改变
		for(int i=0;i<fd1.a.length;i++)
			fd1.a[i]++;    //这里是正确的,因为final int[]={1,2,3,4,5,6}表示的是常量数组,而数组里值不是常量
		//fd1.a=new int[3];   此处错误,常量数组不可改变
		//fd1.v2=nwe Value(); 此处错误,v3是常量
		//fd1.v3=new Value(); 此处错误,v2是常量
		
		fd1.print("fd1");
		System.out.println("Creating new FinalData");
		FinalData fd2=new FinalData();
		fd1.print("fd1");
		fd2.print("fd2");
	}
}
值得注意的是这里的final int i4=(int)(Math.random()*20);static final int i5=(int)(Math.random()*20);中,i4和i5是随机生成的数,不能由于某个数据的属性是final,就认定它的值一定能在编译时期就是确定的,因为你再运行一次,它们的值就会可能不同。其他要说的就是:public表示可以在包外使用,static表示它们只有“一个”,final不用说了,表示常量。


对于②:

空白final数据成员这个没什么好说的,就是Java允许创建一种特殊的数据成员,虽然声明为final变量,但却没有赋一个初始值。但是!你用空白final数据成员前,必须对它进行正确的初始化。

例如先前定义的final int i;

为了确保final数据使用前得到正确的初始化,那么你就要在构造方法中对空白final数据成员进行初始化。

                                 #构造方法#(){

                                       i=1;

                                 }


对于③:

final修饰方法参数,意味着方法的内部,不能改变final修饰的参数。是否想到了c++的const关键字

class TestFinal{
	public void spin(){
	}
}
public class FinalArgument {
	void with(final TestFinal g){
		//g=new Gizmo(); 次数错误,g是final的,不可改变
		g.spin();
	}
	void without(TestFinal g){
		g=new TestFinal();
		g.spin();
	}
	//void f(final int i){  此处错误,不能改变参数final常量i
	//   i++;
    // }
	int g(final int i){
		return i+1;  //只能对final参数做简单的引用
	}
	public static void main(String[] args){
		FinalArgument bf=new FinalArgument();
		bf.without(new TestFinal());  //这里可以传递一个NULL指针,不会有编译错误,即bf.without(NULL);
		bf.with(new TestFinal());
	}
}
在f()中,只能读取参数,不能改变它。在g()中,返回值的改变没有发生在变量本身,只是将final的参数i加了1后直接进行返回。


对于④:

也就是说final修饰的方法不能被重定义。一是为了加锁,二是为了效率,具体的这里不说,因为我也不清楚。


对于⑤:

如果整个类是用final修饰的,出于安全考虑,就是不允许从这个类继承任何内容。有一点要说的是,final类中的成员可以是final的,也可以不是。结果只是禁止继承,没有对其中的成员限制。

例如说:

class Aaa{

   ....

}

final class Bbb{

  ....

  Aaa a=new Aaa();

}

若class Ccc extends Bbb{则是错误的!

   ....

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值