• 夯实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()方法对其进行初始化,他要在运行期才能知道其值。

  • 相关阅读:
    XML与JSON的对比
    WPF dataGrid下的ComboBox的绑定
    WPF 导出Excel(合并单元格)
    WPF x:key和x:name用法
    WPF Canvas
    WPF Visibility属性用法
    AxInterop.ShockwaveFlashObjects.dll 问题
    BadImageFormatException,未能加载正确的程序集XXX的解决办法
    inner join ,left join ,right join区别
    Mac系统下php.ini的位置
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/11241293.html
Copyright © 2020-2023  润新知