夯实Java基础(九)——final关键字

1、前言

Java语言中的final关键字,想必大家都不是很陌生,我们自己用的最多的应该是用来定义常量吧,那么今天我们就来了解final这个关键字的用法,这个关键字还是非常简单的。

final从字面意思是不可更改的,最终的意思,它可以用来修饰类、方法、变量(包括成员变量和局部变量)、参数。

2、final修饰类

final修饰类,表示该类不能再被继承了,如果一个类它的功能比较完整,不需要扩展功能,我们就可以使用final来修饰。我们最常用String、Integer、System等类就是用final修饰的,其不能再被其他类所继承。

用final修饰类如果被继承了那么在编译的时候就会报错。

3、修饰方法

final修饰方法,表示这个方法不能被子类方法重写。如果你认为一个方法的功能已经足够完整了,不需要再去子类中扩展的话,我们可以声明此方法为final。比如Object类中getClass()方法就是final修饰的。

 

注意:类中所有的private方法都自动成为final。由于不能访问一个private方法,所以它绝对不会被覆盖。

4、修饰变量

final修饰变量表示是常量,一般都和static一起使用,用来定义全局常量。final无论修饰的是成员变量还是局部变量,都必须进行显式初始化,如下。

 1 public class FinalTest {
 2     //显式初始化
 3     final int AA=11;
 4     final int BB;
 5     final int CC;
 6     final int DD;
 7     //构造代码块初始化
 8     {
 9         BB=22;
10     }
11     //构造方法初始化
12     public FinalTest(){
13         CC=33;
14         DD=44;
15     }
16 
17     public FinalTest(int CC, int DD) {
18         this.CC = CC;
19         this.DD = DD;
20     }
21 }

我们可以通过显式初始化、构造代码块初始化、构造方法初始化这三种方式对final修饰的变量进行初始化。

前面都是讲的final修饰基本数据类型的变量,如果final修饰引用变量会是怎么样,我们来看一下举例:

 1 public class FinalTest {
 2 
 3     public static void main(String[] args) {
 4         final AA aa = new AA();
 5         //这里在引用其他的对象就会报错Cannot assign a value to final variable 'aa'
 6         //aa=new AA();
 7         aa.i++;
 8         System.out.println(aa.i);
 9     }
10 
11 }
12 
13 class AA{
14     int i;
15 }
16 
17 //运行结果:1

可以看到,虽然我们将引用变量用final修饰了,但是该对象的变量 i 我们还是可以进行修改,而这个变量的引用不能再指向另一个对象了。表明final修饰的是引用变量,就不能再指向其他对象,但是如果该对象内的变量不是final修饰的,其变量的值是可以进行修改的。

5、修饰参数

final修饰参数准确的来说应该是修饰形参,表明该形参的值不能被修改。

 1 public class FinalTest {
 2 
 3     public static void main(String[] args) {
 4         FinalTest f=new FinalTest();
 5         f.show(5);
 6     }
 7 
 8     public void show(final int param){
 9         //编译报错:Cannot assign a value to final variable 'param'
10         //param=10;
11         System.out.println(param);
12     }
13 }

我在使用final修饰形参时,表明此形参是一个常量。当我们调用方法的时候,给形参进行赋值,一旦赋值以后,就只能在该方法使用,而且不能进行重新赋值操作,否则编译报错。如果形参是引用类型,则引用变量不能再指向其他对象,但是该对象的内容是可以改变的。

6、类的final变量和普通变量有什么区别?

参考链接:https://www.cnblogs.com/xiaoxi/p/6392154.html

当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要保证在使用之前被初始化赋值即可)必须在定义时或者构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后,就不能再被赋值了。那么final变量和普通变量到底有何区别呢?下面请看一个例子:

 1 public class Test { 
 2     public static void main(String[] args)  { 
 3         String a = "hello2";   
 4         final String b = "hello"; 
 5         String d = "hello"; 
 6         String c = b + 2;   
 7         String e = d + 2; 
 8         System.out.println((a == c)); 
 9         System.out.println((a == e)); 
10     } 
11 }

输出结果:true、false
     大家可以先想一下这道题的输出结果。为什么第一个比较结果为true,而第二个比较结果为fasle。这里面就是final变量和普通变量的区别了,当final变量是基本数据类型以及String类型时,如果在编译期间能知道它的确切值,则编译器会把它当做编译期常量使用。也就是说在用到该final变量的地方,相当于直接访问的这个常量,不需要在运行时确定。这种和C语言中的宏替换有点像。因此在上面的一段代码中,由于变量b被final修饰,因此会被当做编译器常量,所以在使用到b的地方会直接将变量b 替换为它的值。而对于变量d的访问却需要在运行时通过链接来进行。想必其中的区别大家应该明白了,不过要注意,只有在编译期间能确切知道final变量值的情况下,编译器才会进行这样的优化,比如下面的这段代码就不会进行优化:

 1 public class Test { 
 2     public static void main(String[] args)  { 
 3         String a = "hello2";   
 4         final String b = getHello(); 
 5         String c = b + 2;   
 6         System.out.println((a == c)); 
 7   
 8     } 
 9       
10     public static String getHello() { 
11         return "hello"; 
12     } 
13 }

这段代码的输出结果为false。这里要注意一点就是:不要以为某些数据是final就可以在编译期知道其值,通过变量b我们就知道了,在这里是使用getHello()方法对其进行初始化,他要在运行期才能知道其值。

转载于:https://www.cnblogs.com/tang-hao-/p/11241293.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值