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

     在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量)。下面就从这三个方面来了解一下final关键字的基本用法。

    1.修饰类

       当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

     在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。

    2.修饰方法

      使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升。在最近的Java版本中,不需要使用final方法进行这些优化了。

      只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。

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

    3.修饰变量

    修饰变量是final用得最多的地方.首先了解一下final变量的基本语法:

      对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

    上面的一段代码中,对变量i和obj的重新赋值都报错了。

     final 用于声明属性(常量),方法和类,分别表示属性一旦被分配内存空间就必须初始化

     final这个关键字的含义是“这是无法改变的”或者“终态的”;

    那么为什么要阻止改变呢?

     java语言的发明者可能由于两个目的而阻止改变:

    1).效率问题:
        jdk中的某些类的某些方法,是不允许被用户覆盖的,设计者可能认为,所用方法已经是最好的方法,用户私自覆盖,或是由于疏忽而覆盖,就会影响JVM或是系统的系能;
    2). 设计所需:
        众所周知,有些情况必须使用final关键字,比如方法中的匿名内部类的参数传递

        【修饰变量】:
         final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
        【修饰方法】:
         final方法不能被子类方法覆盖,但可以被继承。
        【修饰类】:
         final类不能被继承,没有子类,final类中所有方法都是final的。(如String类)

    1.被final修饰而没有被static修饰的类的属性变量只能在两种情况下初始化:(必须初始化)
    a.在它被声明的时候赋值 
    b.在构造函数里初始化

    解释:   

      当这个属性被修饰为final,而非static的时候,它属于类的实例对象的资源(实例常量),当类被加载进内存的时候这个属性并没有给其分配内存空间,而只是 定义了一个变量a,只有当类被实例化的时候这个属性才被分配内存空间,而实例化的时候同时执行了构造函数,所以属性被初始化了,也就符合了当它被分配内存 空间的时候就需要初始化,以后不再改变的条件.

    2.被static修饰而没有被final修饰的类的属性变量只能在两种情况下初始化:(可以不初始化)
    a.在它被声明的时候赋值
    b.在静态或非静态快里初始化

    解释:
      当类的属性被同时被修饰为static时候,他属于类的资源(类变量),在类加载后,进行连接时候,分三步: 先验证;然后准备,准备时,先分配内存,接着默认初始化;可以进行解析。最后,进行类初始化,类初始化前,必须保证它的父类已经初始化了,所以最先初始化的是超类,对于接口,不必初始其父接口。类初始化时,它把类变量初始化语句及静态初始化语句放到类初始化方法中,所以,如果无此两种语句,也就没<clinit>类初始化方法,而构造函数是在当类 被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候执行,且只执行这一次,所以在 static块中可以被初始化.

    3.同时被final和static修饰的类的属性变量只能在两种情况下初始化:(必须初始化)

    a.在它被定义的时候
    b.在类的静态块里初始化 
    c.特别对于初始化时候调用抛出异常的构造函数,初始时候注意,特别是在实现单例模式时(只能这么初始化)

    class A
    { 
    private final static A a;
    static
    {
    try
    {
    a=new A();
    }catch(Exception e)
    {
    throws new RuntimeException(e);          //必须有,不然不能完成常量的正确初始化
    }
    }
    private A() throws Exception{}
    }

    解释:
      当类的属性被同时被修饰为static和final的时候,他属于类的资源(类常量),那么就是类在被加载进内存的时候(也就是应用程 序启动的时候)就要已经为此属性分配了内存,所以此时属性已经存在,它又被final修饰,所以必须在属性定义了以后就给其初始化值.而构造函数是在当类 被实例化的时候才会执行,所以用构造函数,这时候这个属性没有被初始化.程序就会报错.而static块是类被加载的时候执行,且只执行这一次,所以在 static块中可以被初始化.

     java中的 final变量==常量

    【final变量的变与不变】:final表示变量的值或引用不变
        有人说final变量在赋值后就不可变,此变量可以是基本数据类型+String或者是对象
        那么这个不变到底指的是什么呢?
        这个不变指的是引用,是地址,而所引用的对象的内容仍然是可变的。注:如果为对象,注意此时类初始化条件
        就是说,这个final变量永远指向某个对象,是一个常量指针,而不是指向常量的指针。

    【final关键字的具体应用】:
        【final+变量】:
            在实际应用中,这种形式是非常少见的。
            比如logger是可以的,但是貌似并不是非常实用,或许用户仍然希望通过setter来改变logger变量。
        【static+final+变量】:
            常量。经常使用。
        【final+方法】:
            JDK中常用,但是自己并未常用。
        【final+类】:
            helper类经常使用。
        【final用于匿名内部类的参数传递】:
            在多线程测试时,经常使用。
        【final用于方法的参数】:
            并不常用。   

    延伸:

    在interface里面的变量都是public static final 的。所以你可以这样写:
    public static final int i=10;
    或则
    int i=10;(可以省略掉一部分)
    注意在声明的时候要给变量赋予初值

    解释:

    首先你要弄清接口的含义.接口就是提供一种统一的’协议’,而接口中的属性也属于’协议’中的成员.它们是公共的,静态的,最终的常量.相当于全局常量.
           抽象类是不’完全’的类,相当于是接口和具体类的一个中间层.即满足接口的抽象,也满足具体的实现.
           如果接口可以定义变量,但是接口中的方法又都是抽象的,在接口中无法通过行为来修改属性。有的人会说了,没有关系,可以通过实现接口的对象的行为来修改接口中的属性。这当然没有问题,但是考虑这样的情况。如果接口A中有一个public访问权限的静态变量a。按照java的语义,我们可以不通过实现接口的对象来访问变量a,通过A.a = xxx;就可以改变接口中的变量a的值了。正如抽象类中是可以这样做的,那么实现接口A的所有对象也都会自动拥有这一改变后的a的值了,也就是说一个地方改变了a,所有这些对象中a的值也都跟着变了。如果可以修改值:这和抽象类有什么区别呢,怎么体现接口更高的抽象级别呢,怎么体现接口提供的统一的协议呢,那还要接口这种抽象来做什么呢?所以接口中不能出现变量,如果有变量,就和接口提供的统一的抽象这种思想是抵触的。所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。
           通俗的讲,你认为是要变化的东西,就放在你自己的实现中,不能放在接口中去,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现implements)开放,接口是对开闭原则的一种体现。

  • 相关阅读:
    75. Sort Colors
    101. Symmetric Tree
    121. Best Time to Buy and Sell Stock
    136. Single Number
    104. Maximum Depth of Binary Tree
    70. Climbing Stairs
    64. Minimum Path Sum
    62. Unique Paths
    css知识点3
    css知识点2
  • 原文地址:https://www.cnblogs.com/hwaggLee/p/4491441.html
Copyright © 2011-2022 走看看