- 浏览: 164399 次
- 性别:
- 来自: 重庆
文章分类
最新评论
-
lilixu:
Netcdf (二) -
publicorprivate:
[b]atwr s [/b]
xml和实体对象相互转换 一步到位 -
mangolms:
讲得很好,顶一个
Java 线程入门 -
crawler:
lvwenwen 写道求问楼主自己学习的总结还是有什么相关的材 ...
第二章 面向对象的几个基本原则 -
lvwenwen:
求问楼主自己学习的总结还是有什么相关的材料
第二章 面向对象的几个基本原则
final关键字可以理解为“这个东西不能改变”。之所以要禁止改变,可能是因为实际业务情况需要或者效率或者设计因素,比如说应用中的全局变量我们经常将其用static加final关键字声明保证不能改变且该类的所有对象只有一份。在声明为final的地方有成员变量、方法、类。
final成员变量:
往往我们在用final声明为是常数数据的时候,可以分为编译期的常数数据和运行期的常数数据。
什么叫编译期的常数数据?是指在程序在编译期间已经将数据通过过程的形式存在了class文件中了,这部分数据在不需要在运行期间去执行,相当于节省了一部分开销,这类数据必须是属于基本数据类型(boolean、byte、char、short、int、float、long、double)且必须赋予一个初始值这样一经初始化就在编译期间设定了不能再改变。这类变量的声明我们习惯性的用大写来命名。
public class FinalTest { public static final int A = 5; public static void main(String[] args) { //FinalTest.A = 5; 编译不能通过 因为final声明的数据一旦指定不能改变 } }
什么叫运行期初始化的常数?是指该变量的初始化数据必须在运行期间才能被指定,一旦指定后就不会改变,在这里包括基本数据类型的指定和对象句柄的指定。基本数据类型的指定后是不可改变的,对象句柄的指定后也是不可改变的,但他的不同点是该句柄始终指向到一个具体的对象,而且该句柄始终指向这一对象,但是这一对象本身是可以改变的。
class Student { private int age; public Student(int age){ this.age = age; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class FinalTest { public static final int A = 5; final int b = (int) (Math.random() * 4); static final int staticb = (int) (Math.random() * 4); final Student p = new Student(20); public static void main(String[] args) { FinalTest test = new FinalTest(); FinalTest test2 = new FinalTest(); System.out.println(test.b);//b在运行期被初始化,一旦初始化后就不会改变 System.out.println(test2.b);//b在运行期被初始化,一旦初始化后就不会改变 System.out.println(test.staticb);//staticb在运行期被初始化,一旦初始化后就不会改变 System.out.println(test2.staticb);//staticb在运行期被初始化,一旦初始化后就不会改变 与b不同的是加了static关键字所以test2.staticb值与test.b值一样 //test.p = new Student(15);//编译不通过 ,对象句柄的指定后也是不可改变的,该句柄始终指向到一个具体的对象(就是之前初始化的那个对象) System.out.println(test.p.getAge()); test.p.setAge(21);//但是值是指向的对象本身是可以改变的 System.out.println(test.p.getAge()); } }
在《thinking in Java》中的中文翻译中这句话个人觉得是有问题的:无论static还是final字段,都只能存储一个数据,而且不得改变。
英文中是:A field that is both static and final has only one piece of storage that cannot be changed .
我的理解是只有final声明的字段是只能存储一个数据而且不得改变,事实上static单独声明的字段是可以改变数据的。英文的正确翻译应该是“字段同时由static和final声明后都只能存储一个数据,而且不得改变”。
final方法:
之所以要使用final方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的行为在继承期间保持不变,而且不可被覆盖或改写,就可以采取这种做法。
采用final方法的第二个理由是程序执行的效率。只要编译器发现一个final方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内实际代码的一个副本来替换方法调用。这样做可避免方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能提升。因为任何提升都被花在方法内部的时间抵消了。Java编译器能自动侦测这些情况,并颇为“明智”地决定是否嵌入一个final方法。然而,最好还是不要完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,才应考虑将一个方法设为final。 final类: 如果说整个类都是final(在它的定义前冠以final关键字),就表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作。换言之,出于这样或那样的原因,我们的类肯定不需要进行任何改变;或者出于安全方面的理由,我们不希望进行子类化(子类处理)。 设计一个类时,往往需要考虑是否将一个方法设为final。可能会觉得使用自己的类时执行效率非常重要,没有人能覆盖自己的方法。这种想法在某些时候是正确的。但要慎重作出自己的假定。通常,我们很难预测一个类以后会以什么样的形式再生或重复利用。常规用途的类尤其如此,若将一个方法定义成final,就杜绝了在其他程序员的项目中对自己的类进行继承的途径。class FinalFather {
public final void say(String str){
System.out.println(str);
}
}
public class FinalTest extends FinalFather{
public void say(String str){//编译不通过
System.out.println(str);
}
}
将类定义成final后,结果只是禁止进行继承——没有更多的限制。然而,由于它禁止了继承,所以一个final类中的所有方法都默认为final,但是成员变量默认是没加的。因为此时再也无法覆盖它们。所以与我们将一个方法明确声明为final一样,编译器此时有相同的效率选择。final class FinalFather {
//final int a = 5;
int a = 5;
public void say(String str){//默认也是带有final的
System.out.println(str);
}
}
//class FinalChild extends FinalFather{}//编译不通过
public class FinalTest{
public static void main(String[] args) {
FinalFather f = new FinalFather();
f.a=10;//如果把FinalFather中的a声明为final则编译不通过说明final类的成员变量是没有加自动加上fianl的只有方法自动加上了final限制
System.out.println(f.a);
}
}
评论
发表评论
-
将博客搬至CSDN
2017-05-24 18:01 352将博客搬至CSDN -
第八章 装饰模式
2013-05-17 08:55 10491.装饰模式 动态地给对象添加一些额外的职责。就功能来说 ... -
Java基本类型与byte数组之间相互转换
2013-05-15 18:07 4297转:http://blog.sina.com.cn/s/bl ... -
Java 线程入门
2013-05-09 15:28 14741概念 线程,有时被称为轻量级进程(Lightweigh ... -
Java IO流 续
2013-05-08 09:39 13301.基于字节文件读写 FileInputStream和F ... -
Java IO流
2013-05-08 09:16 15071.流的概念 流是一个很形象的概念当程序需要读取数据的 ... -
EJB实体bean之间的关系-ORM
2013-05-06 08:05 12201.ORM: Object Relational ... -
第四章 简单工厂模式
2013-05-05 15:02 10021.简单工厂模式 简单工厂模式又叫做静态工厂方法模式。它 ... -
第三章 单例模式
2013-05-05 14:52 8593.1单例(Singleton)模式 保证一个类仅有一个 ... -
第二章 面向对象的几个基本原则
2013-05-05 14:42 23072.1 抽象类和接口 抽象类是可以继承一个抽象类 ... -
第一章 设计模式与简介
2013-05-05 14:16 11471.1什么是设计模式 人们在自己的环境中不断发现问题和寻 ... -
frameset session失效后 返回到 顶层登陆页面
2013-04-23 14:26 829采用frameset来布局网页的时候,可能由于session ... -
Xstream-xml和实体对象相互转换特殊问题
2012-09-06 18:39 6369之前发了一篇博文《xml和实体对象相互转换 一步到位 》 ... -
理解JMS
2012-09-06 16:31 2204首先JMS存在的理由: RPC(Remote proced ... -
系统权限设计
2012-09-05 21:56 1733主体对象: 1.用户 2. ... -
xml和实体对象相互转换 一步到位
2012-09-05 14:05 5399用Xstream完成xml与对象之间的相互转换,我在xstre ... -
回望Java中的多线程并发(一)
2012-09-05 08:55 1731并发其实并不等于多线程,可以理解为多线程是实现并发的一种方式, ... -
Java内存区域与内存溢出异常
2012-09-02 18:56 1422之前根据平时的积累总 ... -
回望Java中Static关键字
2012-09-01 09:41 3841编写代码过程中常常用 ... -
Java内存分配
2012-08-31 14:56 3486前言: 工作时间稍微长一些之后,总是对一些不能看到的东西会有 ...
相关推荐
回望期权
有交易费的时间依赖型回望期权的定价研究,王建稳 ,王利伟,假定标的资产模型中的参数为时间的函数(即无风险利率为r(t),标的资产的期望回报率为u(t),标的波动率为l(t)以及红利率为q(t)) ,利用风�
高中历史之图说历史回望太平天国素材
跳-扩散价格过程下有交易成本的回望期权定价研究,袁国军,杜雪樵,本文主要研究了跳-扩散价格过程下有交易成本的回望期权的定价问题,利用广义Ito公式,得到了在该模型下期权价格所满足的微分方程�
跳-扩散模型中的回望期权定价,赵见,秦军,在实际金融市场中,由于重要的新信息的到达会对股票的价格产生冲击,这时股票价格往往会出现间断的“跳跃”,其定价问题远比标的
餐饮行业深度分析-回望美国餐饮历程,看中国餐饮发展趋势.docx
回望Java——设计为Jvm一体的特性,Java是Jvm与编程人员的或窃窃私语,或雅望高谈(不过由于Java与Jvm背负了太多历史,GraalVM出来探路) Jvm的设计理念 平台无关性 和 语言无关性 Android设计理念 全面贴合TCP/IP...
回望专用记事本源码.rar
CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht CPU历史之旅--回望过去的脚步.mht
第一框 回望成长课件
Java面试SQL查询语句突击练习突击,对你面试绝对有帮助。请放心下载学习
完整版回望专用记事本源码.rar
回望专用记事本源码.e.rar
java面试常问基础知识总结(超经典),对你的面试绝对有帮助。
《回望成长》PPT优秀教学课件
《回望成长》PPT优质教学课件
java面试多线程高并发相关回家技巧(超经典),对你的面试绝对有用,请放心学习
完整版回望专用记事本源码.e.rar
奇异期权的蒙特卡洛定价,包含美式、回望、障碍期权
回望期权的定价,有意者自取。希望能帮助到大家。