zoukankan      html  css  js  c++  java
  • Java-final关键字

    ---恢复内容开始---

    final关键字是Java中一个比较重要的关键字,今天我们就来看看他的用法。

    一、final关键字的基本用法

    在Java中,final关键字可以用来修饰类方法和变量(包括成员变量和局部变量)。下面我们分贝从三方面看一下final关键字的基本用法。

    1、修饰类

      当用final修饰一个类的时候,表明这个类不能被继承。也就是说,如果一个类永远不让他被继承,就可以用final来修饰。

    其中final类中的成员变量可以根据需要设为final,但是final类中的所有成员方法都会隐式设为final方法。

     1 package cn.zpoor.test;
     2 
     3 public final class Main {
     4     public Main(){
     5         
     6     }
     7 }
     8 
     9 //报错
    10 class Test extends Main {//The type Test cannot subclass the final class Main
    11     
    12 }

        在使用final修饰类的时候,要注意谨慎选择,除非确定在设计类的时候,这个类不会用来继承。但是出于安全考虑,最好不要将类设计为final类

    2、修饰方法

    使用final方法的原因:第一个原因是把方法锁定,以防止任何继承类修改它的含义。

              第二个原因是效率。在早期Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可以看不到内嵌

            调用带来的任何性能提升。在最近java版本中,不需要使用final方法进行这些优化了。因此,如果只有在想明确禁止该方法的

              子类中被覆盖的情况下才将方法设置为final。

    注意:类的private方法会隐式的被指定为final方法

    3、修饰变量

    如果修饰的是基本类型变量,则数值一旦初始化之后就不能改变。

    如果修饰的是引用类型的变量,则在初始化之后不能让其指向另一个对象。

    举个栗子:

     1 public class Main {
     2     private final int i = 0;
     3     
     4     public Main() {
     5         i = 1;//报错  The final field Main.i cannot be assigned
     6         final Object obj = new Object();
     7         obj = new Object();//报错  
     8         //The final local variable obj cannot be assigned. 
     9         //It must be blank and not using a compound assignment
    10     }
    11 }

    二、深入理解final关键字

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

      当用final作用于类的成员变量时,成员变量(注意是类的成员变量,局部变量只需要在使用初始化之前被赋值即可)

      必须在定义时或者在构造器中进行初始化赋值,而且final变量一旦被初始化赋值之后就不能被改变。

    举个栗子:

     1 public class Main {
     2     public static void main(String[] args) {
     3         String a = "zpoor2";
     4         final String b = "zpoor";
     5         String d = "zpoor";
     6         String c = b + 2;
     7         String e = d + 2;
     8         
     9         System.out.println((a == c));
    10         System.out.println((a == e));
    11     }
    12 }
    13 
    14 /*结果是:
    15     true 
    16     false*/

    结果分析:

        当final变量是基本类型以及String类型,如果编译期间能够直到确切值,则编译器就会吧他当成编译器常量使用。相当于直接使用这个常量,其他变量则要链接才能使用。需要注意的是只有直到确切final值,编译器才会这样的优化,下面这段代码不会进行优化。

     1 public class Main {
     2     public static void main(String[] args) {
     3         String a = "zpoorlove";
     4         final String b = getHello();//final的值不是确切的
     5         String c = b + "love";
     6         System.out.println((a == c));
     7     }
     8     
     9     public static String getHello() {
    10         return "Hello";
    11     } 
    12 }
    13 
    14 /*结果是:
    15     false*/

    2、被final修饰的引用变量只想的对象内容可变吗?

    举个栗子:

     1 public class Main {
     2     public static void main(String[] args) {
     3         final Test test = new Test();
     4         System.out.println(++test.i);
     5     }
     6     
     7 }
     8 
     9 class Test {
    10     public int i = 0;
    11 }
    12 
    13 /*结果是:
    14     1
    15 */

    顺利通过,说明引用变量被final修饰之后,最然不能指向其他对象,但是它指向的对象的内容是可以改变的。

    3、final 和 static (我经常搞混淆)

      static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。

     1 public class Main {
     2     public static void main(String[] args) {
     3         Test test1 = new Test();
     4         Test test2 = new Test();
     5         
     6         System.out.println(test1.i);
     7         System.out.println(test1.j);
     8         System.out.println(test2.i);
     9         System.out.println(test2.j);
    10     }
    11     
    12 }
    13 
    14 class Test {
    15     public final int i = (int)(Math.random()*10);
    16     public static int j = (int)(Math.random()*10);
    17 }
    18 
    19 /*结果是:
    20     
    21 */

    可以看出:每次打印的两个j的只都是一样的,而i的值则是不同的。

  • 相关阅读:
    还不懂MySQL索引?这1次彻底搞懂B+树和B-树
    11条MySQL规范,你知道的有几个?
    4个点说清楚Java中synchronized和volatile的区别
    还不知道如何实践微服务的Java程序员,这遍文章千万不要错过!
    14个Java并发容器,你用过几个?
    分布式事务解决方案,中间件 Seata 的设计原理详解
    一篇文章搞明白Integer、new Integer() 和 int 的概念与区别
    一线大厂面试官最喜欢问的15道Java多线程面试题
    70道阿里百度高频Java面试题(框架+JVM+多线程+算法+数据库)
    关于spark当中生成的RDD分区的设置情况。
  • 原文地址:https://www.cnblogs.com/zpoor/p/7600173.html
Copyright © 2011-2022 走看看