`
tohsj0806
  • 浏览: 21599 次
  • 性别: Icon_minigender_2
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

java中final的学习笔记

阅读更多

关于final关键字,总是那么些疑惑,今天就总结一下。

一.final的概念:在Java中, 可以使用final关键字修饰类、方法以及成员变量。

1.final标记的类不能被继承;
在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。

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

3.final标记的变量即成为常量,只能被赋值一次.

二、final的用法
1、final 对于常量来说,意味着值不能改变,例如 final int i=100。这个i的值永远都是100。
但是对于变量来说又不一样,只是标识这个引用不可被改变,例如 final File f=new File("c:\\test.txt");那么这个f一定是不能被改变的,如果f本身有方法修改其中的成员变量,例如是否可读,是允许修改的。有个[/size][size=medium][size=large][/size]形象的比喻:一个女子定义了一个final的老公,这个老公的职业和收入都是允许改变的,只是这个女人不会换老公而已。

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

3、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解释字节码的时间。

 

分享到:
评论
3 楼 tohsj0806 2014-12-02  
http://blog.csdn.net/whuslei/article/details/6251020
局部内部类引用外部类中的局部变量必须是final属性的!
2 楼 tohsj0806 2014-12-02  
归纳上述回答的真正核心是:局部内部类对象中包含有要访问的final型局部变量的一个拷贝,成为它的数据成员。因此,正是在这个意义上,final型局部变量的生命期,超过其方法的一次调用。严格来说,方法调用结束,所有的局部变量(含final)全死亡了。但:局部内部类对象中有final型局部变量的拷贝。
1 楼 tohsj0806 2014-12-02  
今天看到,局部内部类要使用局部变量,那么这个局部变量必须是final的
原因是final的使这个局部变量的生命周期超越了这个方法。


我的问题是: final对象的生命周期为什么可以超越定义这个对象的方法?
            
答:这个问题问得好。许多的JAVA书,这个问题都是“含含糊糊”的。
1)所谓“局部内部类”就是在对象的方法成员内部定义的类。而方法中的类,访问同一个方法中的局部变量,是天经地义的。那么为什么要加上一个final呢?
2)原因是:编译程序实现上的困难,难在何处:内部类对象的生命周期会超过局部变量的生命期。为什么?表现在:局部变量的生命期:当该方法被调用时,该方法中的局部变量在栈中被创建(诞生),当方法调用结束时(执行完毕),退栈,这些局部变量全部死亡。而:内部类对象生命期,与其它类一样,当创建一个该局部类对象后,只有没有其它人再引用它时,它才能死亡。完全可能:一个方法已调用结束(局部变量已死亡),但该局部类的对象仍然活着。即:局部类的对象生命期会超过局部变量。
3)退一万步:局部类的对象生命期会超过局部变量又怎样?问题的真正核心是:如果:局部内部类的对象访问同一个方法中的局部变量,是天经地义的,那么:只要局部内部类对象还活着,则:栈中的那些它要访问的局部变量就不能“死亡”(否则:它都死了,还访问个什么呢?),这就是说:局部变量的生命期至少等于或大于局部内部类对象的生命期。而:正是这一点是不可能做到的
4)但是从理论上:局部内部类的对象访问同一个方法中的局部变量,是天经地义的。所以:经过努力,达到一个折中结果:即:局部内部类的对象可以访问同一个方法中的局部变量,只要这个变量被定义为final.那么:为什么定义为final变可以呢?定义为final后,编译程序就好实现了:具体实现方法是:将所有的局部内部类对象要访问的final型局部变量,都成员该内部类对象中的一个数据成员。这样,即使栈中局部变量(含final)已死亡,但由于它是final,其值永不变,因而局部内部类对象在变量死亡后,照样可以访问final型局部变量。

相关推荐

    Java JDK 5.0学习笔记

    本学习笔记旨在帮助新手全面理解并掌握Java 5.0的关键知识点。 一、泛型(Generics) Java 5.0引入了泛型,它允许在定义类、接口和方法时指定类型参数,从而实现类型安全的集合。泛型消除了强制类型转换的需要,...

    良葛格Java JDK 5.0学习笔记ch05

    在这个"良葛格Java JDK 5.0学习笔记ch05"中,我们将深入探讨其中的关键知识点。 一、泛型 Java 5.0引入了泛型,这是一项强大的类型安全机制,允许在编译时检查类型。泛型可以应用于类、接口和方法,通过指定参数...

    良葛格Java JDK 5.0学习笔记[可打印]

    良葛格的Java JDK 5.0学习笔记是一份宝贵的资源,适合初学者和有经验的开发者回顾这个版本的关键概念。下面我们将详细探讨Java JDK 5.0中的核心知识点。 1. **泛型(Generics)** 泛型是JDK 5.0引入的一项重要特性...

    Java JDK 7学习笔记(国内第一本Java 7,前期版本累计销量5万册)

     《Java JDK 7学习笔记》是作者多年来教学实践的经验总结,汇集了学员在教学过程中遇到的概念、操作、应用或认证考试上的各种问题及解决方案。  《Java JDK 7学习笔记》详细介绍了JVM、JRE、Java SE API、JDK与IDE...

    java学习笔记(一个初学者的java学习笔记)

    ### Java学习笔记——基础知识详解 #### 一、Java基本数据类型及内存占用 Java作为一种广泛使用的编程语言,其基础数据类型对于理解程序的行为至关重要。Java提供了八种基本数据类型,分为数值型、字符型和布尔型...

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

    Java中的`final`关键字、抽象类和接口是面向对象编程中的核心概念,它们共同构建了类的层次结构和多态性。以下是对这些概念的详细解释: 1. **final关键字** - `final`关键字用于确保变量的值一旦被赋值后就不能...

    JAVA学习笔记.pdf

    JAVA学习笔记.pdf 中讲解了JAVA语言的基础知识,包括类的基本知识、成员变量、成员方法、类的实例、内部类、匿名类、接口、包等。 类的基本知识 在JAVA中,类是对象的蓝图,类的声明语法为:[访问控制符] class ...

    JAVA学习笔记

    JAVA学习笔记涵盖了Java编程语言中多个核心概念和特性。通过讲解this关键字、继承、static关键字和代码块、final关键字、多态、方法重写、抽象类与接口、封装与隐藏、垃圾回收、类组合、包装类、对象处理、类成员、...

    java学习笔记.pdf

    ### Java学习笔记知识点总结 #### 第一章:Java语言入门 - **1.1 Java的诞生** Java由Sun Microsystems公司于1995年推出的一种可移植、面向对象的编程语言。最初的设计目标是为消费电子产品提供一种通用编程语言...

    java IO流学习笔记

    ### Java IO流学习笔记 #### 异常处理与IO流操作 在进行Java IO流的学习过程中,异常处理是非常重要的一个方面。本节将详细介绍如何在Java中处理异常,并结合具体的IO流操作进行说明。 #### 一、异常处理 在Java...

    java jdk 5学习笔记

    以下是对这个学习笔记中可能涵盖的知识点的详细解释: 1. **自动装箱与拆箱**: JDK 5引入了自动装箱和拆箱的概念,使得基础类型与对应的包装类之间可以无缝转换。例如,int与Integer,无需手动调用`Integer.value...

    java学习笔记 java学习笔记

    Java学习笔记涵盖了许多核心概念,包括面向对象编程的各个方面。以下是对这些知识点的详细解析: 1. **继承中方法的重写**: 当子类重写父类的方法时,子类方法的访问权限必须至少等于或大于父类中对应方法的访问...

    Java学习笔记(必看经典)

    Java是一种广泛使用的面向...总的来说,Java学习笔记应该涵盖从基础知识到高级特性的全面内容,适合初学者和有一定基础的开发者作为参考。通过不断实践和学习,可以逐步掌握Java编程的精髓,成为一名熟练的Java开发者。

    良葛格Java学习笔记

    以上内容是“良葛格Java学习笔记”中的核心知识点,通过深入学习和实践,可以帮助读者建立起坚实的Java基础,进一步提升编程技能。其中,ch01.pdf可能详细介绍了Java的基础知识,而ch02.pdf可能涵盖了更高级的主题,...

    良葛格Java JDK 5.0学习笔记

    《良葛格Java JDK 5.0学习笔记》是一本专为初学者设计的Java编程教程,它以PDF格式提供,旨在帮助读者掌握Java JDK 5.0版本的关键特性和编程技巧。Java JDK 5.0是Java发展历程中的一个重要里程碑,引入了许多创新...

    JAVA JDK 5.0学习笔记

    良葛格的Java JDK 5.0学习笔记涵盖了这些关键知识点,深入浅出地解析了Java编程中的新特性和最佳实践,是理解和掌握JAVA JDK 5.0的宝贵资源。通过学习这些内容,开发者能够提升编程技能,更好地利用Java进行软件开发...

    java私塾学习笔记整理

    ### Java私塾学习笔记整理 #### 第一章:Java入门 **一、Java是什么?** Java是一种广泛使用的高级编程语言,由Sun Microsystems于1995年推出。它旨在为跨平台开发提供一种通用的语言环境,使开发者能够在任何...

Global site tag (gtag.js) - Google Analytics