全面解析java final关键字

根据上下文环境,Java 的关键字 final 的含义有些微的不同,但通常它指的是“这是不能被改变的”。防止改变有两个原因:设计或效率。因为这两个原因相差很远,所以有可能误用关键字 final。

以下几节讨论了可能使用 final 的三个地方:数据、方法和类。

1)final 数据

对于编译时常量这种情况,编译器可以把常量带入计算中,可以减少了一些运行时的负担。在 Java 中,这类常量必须是基本类型,而且用关键字 final 修饰。你必须在定义常量的时候进行赋值。

带有恒定初始值的 final static 基本变量(即编译时常量)命名全部使用大写,单词之间用下划线分隔。

一个被 static 和 final 同时修饰的属性只会占用一段不能改变的存储空间。

当用 final 修饰对象引用而非基本类型时,

  • 对于基本类型,final 使数值恒定不变。
  • 对于对象引用,final 使引用恒定不变。

一旦引用被初始化指向了某个对象,它就不能改为指向其他对象。但是,对象本身是可以修改的,Java 没有提供将任意对象设为常量的方法。(你可以自己编写类达到使对象恒定不变的效果)这一限制同样适用数组,数组也是对象。

示例:

import java.util.*;

class Value {
  int i;
  Value(int i) {
    this.i = i;
  }
}

/**
 * @author Limh
 */
public class FinalData {
  private static Random rand = new Random(47);
  private String id;

  public FinalData(String id) {
    this.id = id;
  }
  private final int valueOne = 9;
  private static final int VALUE_TWO = 99;
  public static final int VALUE_THREE = 39;
  private final int i4 = rand.nextInt(20);
  static final int INT_5 = rand.nextInt(20);
  private Value v1 = new Value(11);
  private final Value v2 = new Value(22);
  private static final Value VAL_3 = new Value(33);
  private final int[] a = {1, 2, 3, 4, 5, 6};

  @Override
  public String toString() {
    return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
  }

  public static void main(String[] args) {
    FinalData fd1 = new FinalData("fd1");
    //v2=new Value(22);
    fd1.v2.i++;
    fd1.v1 = new Value(9);
    //a.length = 6
    for (int i = 0; i < fd1.a.length; i++) {
      fd1.a[i]++;
    }
    System.out.println(fd1);
    System.out.println("Creating new FinalData");
    FinalData fd2 = new FinalData("fd2");
    System.out.println(fd1);
    System.out.println(fd2);
  }
}

输出:

fd1: i4 = 15, INT_5 = 18
Creating new FinalData
fd1: i4 = 15, INT_5 = 18
fd2: i4 = 13, INT_5 = 18

因为第一个变量和第二个变量都是带有编译时值的 final 基本类型,它们都可用作编译时常量,没有多大区别。第三个变量是一种更加典型的常量定义的方式:public 意味着可以在包外访问,static 强调只有一个,final 说明是一个常量。

正如你在 main() 中所见,v2 是 final 的并不意味着你不能修改它的值。因为它是引用,所以只是说明它不能指向一个新的对象。

2)空白final

空白 final 指的是没有初始化值的 final 属性。

编译器确保空白 final 在使用前必须被初始化。这样既能使一个类的每个对象的 final 属性值不同,也能保持它的不变性。

你必须在定义时或在每个构造器中执行 final 变量的赋值操作。这保证了 final 属性在使用前已经被初始化过。

3)final参数

在参数列表中,将参数声明为 final 意味着在方法中不能改变参数指向的对象或基本变量:

class Gizmo {
  public void spin() {

  }
}

/**
 * @author Limh
 */
public class FinalArguments {
  void with(final Gizmo g) {
    //-g = new Gizmo();
    // Illegal -- g is final
  }

  void without(Gizmo g) {
    g = new Gizmo(); // OK -- g is not final
    g.spin();
  }

  //void f(final int i) { i++; } // Can't change
  // You can only read from a final primitive
  int g(final int i) {
    return i + 1;
  }

  public static void main(String[] args) {
    FinalArguments bf = new FinalArguments();
    bf.without(null);
    bf.with(null);
  }
}

4) final方法

使用 final 方法的原因有两个。

给方法上锁,防止子类通过覆写改变方法。这是出于继承的考虑,确保方法的行为不会因继承而改变。
只有在为了明确禁止覆写方法时才使用 final。

5) final和private

类中所有的 private 方法都隐式地指定为 final。因为不能访问 private 方法,所以不能覆写它。

6)final类

当说一个类是 final (final 关键字在类定义之前),就意味着它不能被继承。之所以这么做,是因为类的设计就是永远不需要改动,或者是出于安全考虑不希望它有子类。

由于 final 类禁止继承,类中所有的方法都被隐式地指定为 final,所以没有办法覆写它们。你可以在 final 类中的方法加上 final 修饰符,但不会增加任何意义。

以上就是全面解析java final关键字的详细内容,更多关于java final关键字的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java基础教程之final关键字浅析

    前言 前面在讲解String时提到了final关键字,本文将对final关键字进行解析. static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.下面我们来了解一下final关键字及其用法. final从总体上来说是"不可变的",可用于修改类.方法.变量. 一. final类 final修饰的类,该类不能被继承.当你确认一个类永远不会被继承或不想被继承,那么就可以用final修饰. 同样,对于

  • Java this、final等关键字总结

    this 关键字this引用对象自身.它也可以在构造方法内部用于调用同一个类的其他构造方法. 隐藏的静态变量可以通过"类.静态变量"来引用,而隐藏的实例变量就需要使用"this.实例变量"来引用. 调用一个重载的构造方法this引用是必须的. this是个隐式参数,代表当前对象 publie class Student{ private String name; public void setName(String name){ this.name=name; //

  • 详解Java中的final关键字

    1 修饰属性或者变量 无论属性是基本类型还是引用类型,作用都是变量里面存放的"值"不可变 经常和static关键字一起使用,作为常量 1 基本类型,变量放的是实实在在的值,如1,"abc"等 2 引用类型,变量放的是个地址,所以用final修饰引用类型变量指的是它里面的地址不能变,即它只能指向初始时指向的那个对象,而不关心指向的对象内容的变化 所以修饰的变量必须被初始化 public static final String LOAN = "loan&quo

  • 浅谈Java中的final关键字与C#中的const, readonly关键字

    在编程语言中都有某种方式,告知编译器一块数据是恒定不变的.有两个需求 1. 一个永不改变的编译器常量 2. 一个在运行时被初始化的值,而这个值不会被改变 在Java中,使用final修饰变量实现这两个需求 <pre name="code" class="java">//编译器常量 private final int valueOne = 9; private static final int VALUE_TWO = 99; public static f

  • Java中final关键字的使用与注意总结

    前言 在java中可以将实例域定义为final.在构建对象是必须初始化这样的值.必须确保在每个构造器执行之后,这个域的值被设置,并且在后面的操作中不再对其修改.使用final声明变量之后,这个值就不能修改,一般final类型的变量都被声明为静态变量,而且是公有类型的,它在内存中被放在一个特有的公共区域. 也就是说,在Java语法中规定,final修饰的成员变量必须有程序员显式地指定初始值. 定义格式为: public  static  final  double pi = 3.1415926:

  • Java中final关键字详解及实例

    final在Java中可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,如果你试图将变量再次初始化的话,编译器会报编译错误.  final的含义在不同的场景下有细微的差别,但总体来说,它指的是"不可变". 1. final变量 凡是对成员变量或者本地变量(在方法中的或者代码块中的变量称为本地变量)声明为final的都叫作final变量.final变量经常和static关键字一起使用,作为常量.用final关键字修饰的变量,只能进行一次赋值操作

  • 浅析对Java关键字final和static的理解

    一.final 根据程序上下文环境,Java关键字final有"这是无法改变的"或者"终态的"含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final类不能被继承,没有子类,final类中的方法默认是final的. final方法不能被子类的方法覆盖,但可以被继承. final成员变量表示常量,只能被赋值一次,赋值后值不再改变. final不能用于修饰构造方法. 注意:父类的private成员方法是不能被子类方法覆

  • java多线程关键字final和static详解

    这篇文章主要介绍了java多线程关键字final和static详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 final关键字 1.final关键字在单线程中的特点: 1)final修饰的静态成员:必须在进行显示初始化或静态代码块赋值,并且仅能赋值一次. 2)final修饰的类成员变量,可以在三个地方进行赋值:显示初始化.构造代码块和构造方法,并且仅能赋值一次. 3)final修饰的局部变量,必须在使用之前进行显示初始化(并不一定要在定义是

  • Java关键字final、static使用总结

    一.final 根据程序上下文环境,Java关键字final有"这是无法改变的"或者"终态的"含义,它可以修饰非抽象类.非抽象类成员方法和变量.你可能出于两种理解而需要阻止改变:设计或效率. final类不能被继承,没有子类,final类中的方法默认是final的. final方法不能被子类的方法覆盖,但可以被继承. final成员变量表示常量,只能被赋值一次,赋值后值不再改变. final不能用于修饰构造方法. 注意:父类的private成员方法是不能被子类方法覆

  • 学习Java的static与final关键字

    static:(静态修饰符)面向对象中static修饰的内容是隶属于类,而不是直接隶属于对象的,所以static修饰的成员变量一般称作类成员变量,而static修饰的方法一般称作类方法. 分类: 1.static变量,也叫作静态变量或者类变量.另一种是没有被static修饰的变量,叫实例变量. 2.static方法,也叫作静态方法或者类方法,静态方法中不能定义静态变量,实例方法也不能. 3.static代码块,静态块中,可以访问静态变量,调用静态方法. 注意事项: 1.static不依附于任何对

随机推荐