关于java final的方方面面

时间:2021-06-29 04:04:38

按照作用域,final变量分为:

1.class范围的static final var;

2.instance范围的final var;

3.method范围的final var包含final parameters;

其中类级别的final在整个类的命名空间只有一个实例,instance final则每个对象都有各自final的实例,且可以各不相同,method中的final则针对每次调用有一个final变量。

如下代码所示:在每个ClassLoader 加载FinalVariable时classInt被初始化一次以后不会再改变;对于instanceInt,每次创建FinalVariable对象,各个对象包含的instanceInt可能各不相同;而methodInt则每次即使是相同对象的多次调用可能产生不同的int值。

class FinalVariable{

static final int classInt = new Random().nextInt();

final int instanceInt =  new Random().nextInt();

 

public int getMethodInt() {

  final int methodInt = new Random().nextInt();

return methodInt; 

 

---------------------------------------------------------------------------------------------

final常量;

primitive和string类型如果是final的且该final常量由常量值直接赋值,则编译时会在引用处直接替换成对应的常量值。 

 

Final Collections:

Java API Collections中提供了产生不可变集合的接口: 

 

    public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c) {
        return new UnmodifiableCollection<>(c);
    }

 

 只要把Collection变量定义成final的,通过调用类似如上的接口进行赋值,就可以产生一个Immtable的集合了。

其缺点是当修改此集合时无法在编译时监测而要到运行时抛出异常。

 

Final Class:不能被继承的Class,有两只方式:

1.定义类时前面加上final;

2.将类的所有构造器都定义成private的。 

 

Final Method:不能被子类重写的方法(注意可以被重载):

Java默认都是virtual method,C#默认不是virtual method的。C#会强制你去思考为什么要设计成virtual方法,感觉这样更合理。 

 

条件编译:

利用编译器对常量的优化可以做出条件编译的效果:

 class FinalTest{

private static final ISDEBUG= false;

 

 public void getInteger(){

              if(ISDEBUG){

    debug.

               }

         }

 }

 

 Final关键字可以成为我们设计代码的一个有效工具。