你真的会用final关键词吗?

  • 内容
  • 评论
  • 相关

根据上下文环境,Java的关键词final的含义存在着细微的区别,但通常它指的是“这是无法改变的。”不想做改变可能出于两种理由:设计和效率。由于这两个原因相差很远,所以关键字final很有可能被误用。                            ————摘自《Java编程思想》第四版第140页

 

final关键词有三种用法:

  1. 作用于变量
  2. 作用于方法
  3. 作用于类

 

修饰变量

final用的最多的地方就是修饰变量。

final修饰的变量可以是一个永不改变的编译时常量,也可以是一个引用的对象。

当final修饰的变量是一个常量时,这个常量将永远不能被改变,当final修饰的是一个对象时,final就无法再指向另一个对象。

 

final int i = 0;

i = 1;            // Cannot assign a value to final variable 'i'

 

final Object obj = new Object();

obj = new Object();          // Cannot assign a value to final variable 'obj'

 

// 当final修饰的是一个引用的对象时,则不能再指向其他引用了,但当前引用的对象的可以改变,怎么说?

// 假设Object类有一个name属性

obj.setName("zhangsan");

obj.setName("lisi");

 

blank final

Java允许“空白final”,所谓空白final 是指被声明为final但又未给定初值的域。无论什么情况下,编译器都确保空白final在使用前必须被初始化。但是,空白final在关键词final的使用上提供了更大的灵活性,为此,一个类中的final域就可以做到根据对象而有所不同,却又保持其恒定不变的特性。

final String str;

System.out.println(str);         // Variable 'str' might not have been initialized

s = "1";

s = "2";                                 // Variable 'str' might already have been assigned to

 

final 参数

final参数指的是,final关键词修饰方法中形参的参数,意味着你无法在方法中更改参数引用所指向的对象。这是我不能理解的地方,java在传参都是采用值传递,参数的值就是该对象的引用的一个副本,指向同一个对象,对象的内容可以在被调用的方法改变,但对象的引用(不是引用的副本)是永远不会改变的。所以说,就算final修饰方法参数,想防止方法内部不修改其指向的引用对象,这是多此一举。

 

举个例子:定义引用变量A,指向对象B,将A当做参数传入方法,方法里接收参数的是一个引用C,C是A引用的的copy,也指向B,所以说,在方法里想改变B的值,是可以的,但想在方法里想改变A的指向(A指向B),是不可能的。

 

public void changeValue(final Xxx c){

// ...

}

 

修饰方法

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

 

因此,如果明确禁止子类覆写该方法时,可以final关键词修饰方法。

注意:如果父类的方法为private,隐式的说明该方法也是final修饰。

 

修饰类

当用final关键词修饰一个类时,表明该类无法被继承。当使用final关键词修饰类时,其所有成员方法都隐式的被指定为final方法。

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

 

 

若有不正之处,请多多谅解并欢迎指正。

 

每天告诉自己一次:我真的很不错。

喜欢 1

评论

0条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Title - Artist
0:00