`

java final关键字的使用(转)

阅读更多

final变量定义: 变量一经初始化就不能指向其它对象。指向的存储地址不可修改,但指向的对象本身是可以修改的。

先说final变量初始化:

很多文章都这么说:其初始化可以在两个地方,一是其定义处,二是在构造函数中,两者只能选其一。
胡说八道!
final变量可以在任何可以被始化的地方被始化,但只能被初始化一次.一旦被初始化后就不能再次赋
值(重新指向其它对象),作为成员变量一定要显式初始化,而作为临时变量则可以只定义不初始化(当然也不能引用)
即使是作为一个类中的成员变量,也还可以在初始化块中初始化,所以"其初始化可以在两个地方,一是其定义处,
二是在构造函数中,两者只能选其一"是错误的.


作为成员变量时,final字段可以设计不变类,是不变类的一个必要条件但不是一个充要条件.至少可以保证字段不
会以setXXX()这样的方式来改变.但无法保证字段本身不被修改(除非字段本身也是不变类);

对于方法参数的final变量:
对于方法参数的变量定义为final,90%以上的文章都说"当你在方法中不需要改变作为参数的对象变量时,明确使
用final进行声明,会防止你无意的修改而影响到调用方法外的变量。"
胡说八道!

我不知道这个修改是说重新赋值还是修改对象本身,但无论是哪种情况,上面的说法都是错误的.
如果是说重新赋值,那么:
public static void test(int[] x){
  x = new int[]{1,2,3};
}

    int[] out = new int[]{4,5,6};
    test(out);
    System.out.println(out[0]);
    System.out.println(out[1]);
    System.out.println(out[2]);
    调用test(out);无论如何也不会影响到外面变量out.你加不加final根本没有意义.final只会强迫方法内
多声明一个变量名而已,即把x = new int[]{1,2,3};改成int y = new int[]{1,2,3}; 其它没有任何实际意义.
    如果说是修改对象本身:
public static void test(final int[] x){
  x[0] = 100;
}
    int[] out = new int[]{4,5,6};
    test(out);
    System.out.println(out[0]);
难道你用final修饰就不可以修改了?所以说对于方法参数中final是为了不影响调用方法外的变量那是胡说八道的.

那我们到底为什么要对参数加上final?其实对方法参数加final和方法内变量加上final的作用是相同的,即为了将它们
传给内部类回调方法:

abstract class ABSClass{
public abstract void m();
}

现在我们来看,如果我要实现一个在一个方法中匿名调用ABSClass.应该:
public static void test(String s){
     //或String s = "";
  ABSClass c = new ABSClass(){
   public void m(){
      int x = s.hashCode();

      System.out.println(x);

   }
  };
  //其它代码.
}
注意这里,一般而言,回调方法基本上是在其它线程中调用的.如果我们在上面的
     ABSClass c = new ABSClass(){
   public void m(){
       int x = s.hashCode();

       System.out.println(x);

   }
  };
  后面直接调用c.m();应该是没有意义的.但这不重要,重要的是只要有可能是在其它线程中调用,那我们就必须
为s保存引用句柄.

我们先来看GC工作原理,JVM中每个进程都会有多个根,每个static变量,方法参数,局部变量,当然这都是指引用类型.
基础类型是不能作为根的,根其实就是一个存储地址.

GC在工作时先从根开始遍历它引用的对象并标记它们,如此递归到最末梢,所有根都遍历后,没有被标记到的对象说明没
有被引用,那么就是可以被回收的对象(有些对象有finalized方法,虽然没有引用,但JVM中有一个专门的队列引用它
们直到finalized方法被执行后才从该队列中移除成为真正没有引用的对象,可以回收,这个与本主题讨论的无关,包括
代的划分等以后再说明).这看起来很好.

但是在内部类的回调方法中,s既不可能是静态变量,也不是方法中的临时变量,也不是方法参数,它不可能作为根,在内部类
中也没有变量引用它,它的根在内部类外部的那个方法中,如果这时外面变量重指向其它对象,则这个对象就失去了引用,
可能被回收,而由于内部类回调方法大多数在其它线程中执行,可能还要在回收后还会继续访问它.这将是什么结果?

而使用final修饰符不仅会保持对象不会改变,而且编译器还会持续维护这个对象在回调方法中的生命周期.所以这才是final
变量和final参数的根本意义.

分享到:
评论

相关推荐

    Java final关键字

    在Java编程语言中,`final`关键字扮演着一个至关重要的角色,它被用来声明一个变量、方法或类为不可变的。在这个学习demo中,我们将深入理解`final`关键字的各种用法及其背后的原理。 首先,`final`关键字用于变量...

    22.final关键字.zip

    22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22.final关键字.zip22...

    深入理解Java中的final关键字_动力节点Java学院整理

    Java 中的 `final` 关键字是一个至关重要的概念,它被用来声明类、方法和变量,以确保它们在程序执行过程中不可更改。深入理解 `final` 关键字可以帮助开发者写出更加安全、高效的代码。 首先,`final` 关键字可以...

    【Java编程教程】详解Java final 关键字.pdf

    Java中的`final`关键字是一个非常重要的概念,它用于在编程中实现不可变性。...理解并正确使用`final`关键字对于编写安全、可维护的代码至关重要。通过深入学习和实践,开发者可以更好地利用这一特性来提高代码质量。

    Java关键字final、static使用总结

    "Java关键字final、static使用总结" 在 Java 编程语言中,final 和 static 是两个非常重要的关键字,它们可以用来修饰类、方法、变量等,了解它们的使用方法和限制非常重要。本文将详细总结 final 和 static 的使用...

    Java零基础-final关键字.md

    ### Java零基础-final关键字 #### 内容概要 ...通过上述内容的学习和实践,读者不仅能够熟练掌握final关键字的使用方法,还能深刻理解其背后的原理和重要性,从而写出更安全、更高效的Java代码。

    Java编程中static和final关键字的陷阱.pdf

    Java编程中static和final关键字的陷阱是Java开发中两个重要的关键字,但是它们的使用也存在一些陷阱,需要开发者注意掌握。 static关键字可以用于修饰属性、方法和类。static关键字修饰的成员变量称为静态成员变量...

    Java学习笔记---15.面向对象编程10-Java中final关键字,抽象类与接口

    1. **final关键字** - `final`关键字用于确保变量的值一旦被赋值后就不能改变,或者类和方法不能被进一步扩展。 - 当`final`修饰类时,该类不能被继承,如`final class MyClass {}`,这意味着MyClass不能作为其他...

    java final关键字

    ### Java Final 关键字详解 #### 一、引言 在Java编程语言中,`final`关键字具有重要的地位。它能够用于限定类、方法以及变量的行为,并赋予它们特定的属性。本文将深入探讨`final`关键字在不同场景下的具体用法及...

    Java中final关键字详解

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字。另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法。 主要介绍:一.final关键字的基本...

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

    Java中final关键字的使用与注意总结 Java中final关键字的使用与注意总结主要给大家介绍了关于Java中final关键字的相关资料,对大家的学习或者使用Java具有一定的参考学习价值。下面我们将详细介绍final关键字的...

    java中final关键字和static关键字详细用法

    Java中的`final`和`static`关键字是编程中非常重要的两个修饰符,它们分别用于不同的场景,以确保代码的稳定性和高效性。 首先,`final`关键字主要用于表示不可变性。它可以用来修饰类、方法和变量。对于类,如果一...

    java final关键字(基础)(csdn)————程序.pdf

    在Java编程中,使用`final`关键字能够帮助我们确保某些代码的行为是不可变的,从而增加代码的稳定性和安全性。 1. **final变量** - **成员变量**:当`final`修饰类的成员变量时,它必须在构造函数执行完毕前被初始...

    举例讲解Java中final关键字的用法

    Java中的`final`关键字是一个非常重要的概念,它用于表示不可变性或终结状态。下面我们将详细探讨`final`关键字在修饰变量、方法和类时的不同...理解并恰当使用`final`关键字对于编写健壮、高效的Java代码至关重要。

    final关键字详细解读

    final关键字是Java语言中的一个基本概念,它用于限制类、变量、方法以及引用的修改和扩展。final关键字的主要作用是告诉编译器该元素是最终的,不可变的。对于初学者来说,掌握final关键字的使用可以帮助编写出更加...

    Java中的final关键字

    在Java编程语言中,`final`关键字扮演着一个至关重要的角色,它被用来定义不可变性和唯一性。这个关键字可以应用于变量、方法和类,分别赋予它们不同的特性。以下是对`final`关键字在不同场景下使用的详细介绍: 1....

    【Java语言基础】final关键字

    【Java语言基础】final关键字 修饰词:final 最终的最后的 final关键字可用于修饰符,变量和方法,用于表示它修饰的类,方法和方法不可改变。 final 最终的最后的 final修饰变量时,表示该变量一旦获得了初始值之后...

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

    Java中的final关键字 1、修饰类的成员变量 这是final的主要用途之一,和C/C++的const,即该成员被修饰为常量,意味着不可修改。   上面的代码对age进行初始化后就不可再次赋值,否则编译时会报类似上图的错误。 ...

    final 关键字用法

    java程序设计中,final 关键字用法,通过代码演示java程序设计中,final 关键字用法,

Global site tag (gtag.js) - Google Analytics