打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
java final 关键字

来源:java编程思想

 许多编程语言都有某种方法,来向编译器告知一块数据是恒定不变的。有时数据的恒定不变是很有用的,例如:

1,一个编译时恒定不变的常量

2,一个在运行时初始化,而你不希望它被改变。

   对于编译期常量的这种情况,编译器可以将该常量值代入任何可能用到它的计算式中,也就是说,可以在编译期就执行计算式,这减轻了一些运行时的负担。在java中,这类常量必须是基本类型,并且以final表示。在对这个常量定义时,必须进行赋值。

   一个即是static又是fianl的域只占一段不能改变的存储空间。

   当final应用于对象引用时,而不是基本类型时,其含义有些让人疑惑。对基本类型使用fianl不能改变的是他的数值。而对于对象引用,不能改变的是他的引用,而对象本身是可以修改的。一旦一个final引用被初始化指向一个对象,这个引用将不能在指向其他对象。java并未提供对任何对象恒定不变的支持。这一限制也通用适用于数组,它也是对象。

   下面的事例示范fianl域的情况。注意,根据惯例,即是static又是fianl的域(即编译器常量)将用大写表示,并用下划分割个单词


import java.util.Random;

  

class Value {  

  int i; // Package access  

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

public class FinalData {  

  private static Random rand = new Random(47);  

  private String id;  

  public FinalData(String id) { this.id = id; }  

  // Can be compile-time constants:  

  private final int valueOne = 9;  

  private static final int VALUE_TWO = 99;  

  // Typical public constant:  

  public static final int VALUE_THREE = 39;  

  // Cannot be compile-time constants:  

  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);  

  // Arrays:  

  private final int[] a = { 1, 2, 3, 4, 5, 6 };  

  public String toString() {  

    return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;  

  } 

  public static void main(String[] args) {  

    FinalData fd1 = new FinalData("fd1");  

    System.out.println(fd1);

    //! fd1.valueOne++; // Error: can't change value  

    System.out.println(fd1.v2.i);

    fd1.v2.i++; // Object isn't constant!  

    System.out.println(fd1.v2.i);

    fd1.v1 = new Value(9); // OK -- not final  

    System.out.println(fd1.v1.i);

    for(int a : fd1.a)

    System.out.print(a+" ");

    System.out.println();

    for(int i = 0; i < fd1.a.length; i++)  //数组不能再指向其他数组对象,但它指向的数组的内容是可以变的!

      fd1.a[i]++; // Object isn't constant!  



    for(int a : fd1.a)

    System.out.print(a+" ");

    System.out.println();

    //! fd1.v2 = new Value(0); // Error: Can't  

    //! fd1.VAL_3 = new Value(1); // change reference  

    //! fd1.a = new int[3];  

     

    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
22
23
9
1 2 3 4 5 6 
2 3 4 5 6 7 
Creating new FinalData
fd1: i4 = 15, INT_5 = 18
fd2: i4 = 13, INT_5 = 18


     由于valueOne和VALUE_TWO都是带有编译时数值的fianl基本类型,所以它们二者均可以用作编译期常量,并且没有重大区别。VALUE_THREE是一种更加典型的对常量进行定义的方式:定义为public,可以被任何人访问;定义为static,则强调只有一份;定义为fianl,这说明它是个常量。请注意带有恒定初始值(即,编译期常量)的final static基本类型全用大写字母命名,并且字母与字母之间用下划线隔开。

   我们不能因为某些数据是fianl的就认为在编译时可以知道它的值。在运行时使用随机数来初始化i4和INT_5的值叫说明了这一点。事例部分也展示了将fianl数据定义为static和非static的区别。此区别只有当数值在运行时内被初始化时才会显现,这是因为在编译器对编译时的数值一视同仁(并且他们可能因为优化而消失)。当运行时会看见这个区别。请注意,在此fd1和fd2中i4的值是唯一的,每次都会被初始化为15,13。INT_5的值是不可以通过创建第二个FinalData对象加以改变的。这是因为他是static的,在装载类时(也就是第一次创建这个类对象时)已经被初始化,而不是每次创建都初始化。

   


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
java里的final变量
java中final的用法
漫谈.Net关键字系列之一Sealed与Final
Java String源码解析
初始化
猜数字游戏升级版二
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服