java中final在不同情况下使用的特点作用详解

11 篇文章 0 订阅
1 常量(final)的设置是不是只是为了防止程序员在以后修改程序时,忘记这个值是不能修改的?如果假设“程序员一定记得”这个值不允许改变,那么就可以不设为final吧?
2 有些方法的参数中会声明参数为final,这样用有什么用?  例如 public A(final Map map);
回答:::
final不是为了提醒程序员这个值是不能修改的。而是一些值在该程序的使用中是不允许被修改的,则会用到final。如 public A(final Map map);中,使用final修饰符后,map对象相当于只读,在A方法中就不能再对map进行修改。
追问
程序是人写的……程序员不给修改的操作,那个值怎么会被改啊……
回答
1、final类 
 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 

2、final方法 
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。 
使用final方法的原因有二: 
第一、把方法锁定,防止任何继承类修改它的意义和实现。 
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 

3、final变量(常量) 
 用final修饰的成员变量表示常量,值一旦给定就无法改变! 
 final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。  
 另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

4、final参数 
当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

final 对于常量来说,意味着值不能改变。但是对于变量来说又不一样,只是标识这个引用不可被改变,但如果f本身有方法修改其中的成员变量,例如是否可读,是允许修改的。形象的比喻:一个女子定义了一个final的老公,这个老公的职业和收入都是允许改变的,只是这个女人不会换老公而已。


程序的确是人写的,但是为了程序的灵活性,高效性,程序员不能只为了自己的一时想法写代码。而应该联系以后程序的扩展,维护等。
追问
实际上我知道要考虑以后。
不过我之前有这样问
如果假设“程序员一定记得”这个值不允许改变,那么就可以不设为final吧?

假设是一定记得……打死都记得,程序员只有一个,有第二个也记得,就那么绝对的条件下呢?
回答
1、在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 
2、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 
3、final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

从上面的话中应该不难看出,排除程序员记不记的这个问题,使用final从程序内部来说,就使程序灵活性,效率的到提高。这不正是现在追求的灵活和高效么。
追问
恩,基本了解了,谢谢。我还想确定一下 “编译器在遇到调用final方法时候会转入内嵌机制” 这个内嵌机制是什么意思? 解释清楚了……我就把分提高到上限最高值。虽然不知道这个分数有什么意义……
回答
首先,要知道调用一个函数除了函数本身的执行时间之外,还需要额外的时间去寻找这个函数(类内部有一个函数签名和函数地址的映射表)。所以减少函数调用次数就等于降低了性能消耗。

    其次,final修饰的函数会被编译器优化,优化的结果是减少了函数调用的次数。如何实现的,举个例子给你看:
public class Test{
final void func(){System.out.println("g");};
public void main(String[] args){ 
for(int j=0;j<1000;j++)   
func();
}}
经过编译器优化之后,这个类变成了相当于这样写:
public class Test{
final void func(){System.out.println("g");};
public void main(String[] args){ 
for(int j=0;j<1000;j++)  
 {System.out.println("g");}
}}
看出来区别了吧?编译器直接将func的函数体内嵌到了调用函数的地方,这样的结果是节省了1000次函数调用,当然编译器处理成字节码,只是我们可以想象成这样,看个明白。
不过,当函数体太长的话,用final可能适得其反,因为经过编译器内嵌之后代码长度大大增加,于是就增加了jvm解释字节码的时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值