当前位置:首页 > Java技术 > Java编程思想第四版——第十五天

Java编程思想第四版——第十五天

2022年11月07日 21:44:20Java技术16

2012-04-23

121-131/913

 

Java编程思想第四版——第十五天

 

5.5.3 终结条件

通常不能指望finalize(),必须创建其他的“清理”方法,并明确的调用它们。

finalize()另一个用法,不依赖于每次都要对finalize()进行调用,这就是对象终结条件的验证。

 

5.5.4 垃圾回收器如何工作

垃圾回收器提高对象的创建速度有明显的效果。Java从堆分配空间的速度,可以和其他语言从堆栈上分配空间的速度相媲美。

C++的堆——院子,每个对象负责管理自己的地盘,对象被销毁,地盘被重用。

Java虚拟机,堆的实现,像一个传送带,每分配一个新对象,就往前移动一格。这意味着对象存储空间的分配速度非常快。Java的“堆指针”只是简单的移动到尚未分配的区域,效率比得上C++在堆栈上分配空间的效率。在实际过程中在簿记工作方面还有少量额外开销,但比不上查找可用空间开销大。

Java的堆不完全像传送带那样工作,垃圾回收器一面回收空间,一面使堆中的对象紧凑排列。堆指针可以很容易移动到更靠近传送带的开始处,尽量避免了页面错误。通过垃圾回收器堆对象重新排列,实现一种高速的、有无限空间可供分配的堆模型。

引用计数是一种简单但是速度很慢的垃圾回收技术,通常用来说明垃圾收集的工作方式,但从未被应用于任何一种java虚拟机实现中。

更快的模式中,不是基于引用计数计数,依据思想:堆任何“活”的对象,一定能最终追溯到其存活在堆栈活静态存储区之中的引用。

Java虚拟机采用一种自适应的垃圾回收技术,如何处理找到的存活对象,取决于不同的java虚拟机实现。一种:停止-复制(stop-and-copy),空间连续,需要多个空间进行复制转移,适合垃圾多的情况,必须暂停程序,另一种:标记-清扫(mark-and-sweep),空间不连续,不会发生复制,适合垃圾少的情况,必须暂停程序。

自适应技术:自适应的、分代的、停止-复制、标记-清扫式垃圾回收器。

 

Java虚拟机中有许多附加技术用以提升速度,尤其是与加载器操作有关的,被称为“即时”(Just-In-Time,JIT)编译器的技术。把程序全部或部分翻译成本地机器码(这本来是java虚拟机的工作),程序运行速度因此得以提升。Java HotSpot技术采用惰性评估(lazy cvaluation),即时编译器只在必要的时候才编译代码。从不会被执行的代码不会被JIT所编译。Java HotSpot,代码每次被执行的时候都会做一些优化,执行次数越多,速度越快。

 

5.6 成员初始化

Java尽力保证,所有变量在使用前都能得到恰当的初始化,对于方法的局部变量,java以编译时错误的形式来贯彻这种保证。

未初始化的局部变量有可能是程序员的疏忽,如果采用默认值可能掩盖这种失误,因此强制程序员提供一个初始值,可能帮助找出程序里的缺陷。

类的数据成员(即字段)是基本类型,每个基本类型数据成员保证都会有一个初始值。

在类中定义一个对象引用时,如果不初始化,此引用会获得一个特殊值null。

 

5.6.1 指定初始化

直接的:在定义类成员变量的地方为其赋值。(C++中不能这样做)

非基本类型的对象也可以用同样的方法初始化。不初始化就使用,会报空指针的运行时错误。

编译器会恰当的对“向前引用”发出警告。

 

5.7 构造器初始化

可以用构造器进行初始化,运行时刻,可以调用方法或执行某些动作来确定初值,这为编程带来了更大的灵活性。但要记牢:无法阻止自动初始化的进行,它将在构造器被调用之前发生。

编译器不会强制一定要在构造器的某个地方或在使用它们之前对元素进行初始化,因为初始化早已得到了保证。

 

5.7.1 初始化顺序

在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。

 

5.7.2 静态数据的初始化

无论创建多少个对象,静态数据都只占用一份存储区域。Static关键字不能应用于局部变量,因此它只能作用于域。如果一个域是静态的基本类型域,且也没有对它进行初始化,那么它就会获得基本类型的标准初值,如果它是一个对象引用,那么它的默认初始化值就是null。

如果想在定义处进行初始化,采取的方法与非静态数据没什么不同。

静态初始化只有在必要时刻才会进行,如果不创建对象,也不经过类直接引用,那么静态数据永远都不会被创建。只有第一个类对象被创建(或第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化。

初始化的顺序是先静态对象(如果他们尚未因前面的对象创建过程而被初始化),而后是“非静态”对象。要执行main()(静态方法),必须加载StaticInitialization类,然后其静态域被初始化。

 

对象的创建过程,假设有个名为Dog的类:

  1. 即使没有显示的使用static关键字,构造器实际上也是静态方法。首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,java解释器必须查找类路径,以定位Dog.class文件。
  2. 然后载入Dog.class(这将创建一个Class对象),有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。
  3. 当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。
  4. 这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值(对数字来说就是0,对布尔型和字符型也相同),而引用则被设置成了null。
  5. 执行所有出现于字段定义处的初始化动作。
  6. 执行构造器。这可能牵涉很多动作,尤其是涉及继承的时候。

 

5.7.3 显示的静态初始化

Java允许将多个静态初始化动作组织成一个特殊的“静态子句”(有时也叫做“静态块”)。

例如:

public class Spoon{

       static int i;

       static{

              i = 47;

       }

}

尽管上面的代码看起来像个方法,但它实际只是一段跟在static关键字后面的代码。与其他静态初始化动作一样,这段代码仅执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从未生成过那个类的对象)。

 

5.7.4 非静态实例初始化

Java中也有被称为实例初始化的类似语法,用来初始化每一个对象的非静态变量。

实例初始化子句:

{

       mug1 = new Mug(1);

       mug2 = new Mug(2);

       print(“mug1 & mug2 initialized”);

}

看起来和静态初始化子句一模一样,只不过少了static关键字。这种语法对于支持“匿名内部类”的初始化是必须的,但是它也使得可以保证无论调用了哪个显示构造器,某些操作都会发生。实例初始化子句是在构造器之前执行的。

 

作者:凌紫冥
来源链接:https://www.cnblogs.com/53jin/archive/2012/04/23/2466709.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/68412.html

分享给朋友:

“Java编程思想第四版——第十五天” 的相关文章

Java实现Email发送

一、前言最近将项目的登录密码从图形验证码改为了短信验证码,同时也将忘记密码时长度进行了修改,在修改时,想到了之前在一些国外的网站上,使用过邮箱接收验证码的情况,故想到何妨不自己尝试整合一下Java程序发送邮件信息呢,所以动手整合了Email的发送实例。二、Email发送协议想要在互联网上提供电子邮件...

java之整数的分解可以理解为倒序输出

Scanner in=new Scanner(System.in); int number ; number=in.nextInt(); int result=0; do{ int diget=number%10;...

java计数循环及小技巧

要运行一个很大次数的循环应该选择一个小数,然后去判断 例如本例子是100可以选择10去判断 public static void main(String[] args) { // TODO Auto-generated metho...

java高级

java高级

  Java动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。下...

java提高篇(二五)

java提高篇(二五)

      在java中与有两个类都提供了一个多种用途的hashTable机制,他们都可以将可以key和value结合起来构成键值对通过put(key,value)方法保存起来,然后通过get(key)方法获取相对应的value值。一个...

【JAVA】浅谈java枚举类

【JAVA】浅谈java枚举类

一、什么情况下使用枚举类?   有的时候一个类的对象是有限且固定的,这种情况下我们使用枚举类就比较方便? 二、为什么不用静态常量来替代枚举类呢? public static final int SEASON_SPRING = 1; publi...

狂神Java基础总结

狂神Java基础总结

Java基础 Java学习的正确打开方式 学习是一个过程,是一个不断累积、不断沉淀、不断总结、善于传达自己的个人见解以及乐于分享的过程。 链接:https://blog.csdn.net/qq_44543508/article/details/102651841...

JAVA面试精选【Java基础第一部分】

  这个系列面试题主要目的是帮助你拿轻松到offer,同时还能开个好价钱。只要能够搞明白这个系列的绝大多数题目,在面试过程中,你就能轻轻松松的把面试官给忽悠了。对于那些正打算找工作JAVA软件开发工作的童鞋们来说,当你看到这份题目的时候,你应该感动很幸运,因为,只要你把题目中...

java枚举常见用法

用法一:常量   在JDK1.5 之前,我们定义常量都是: public static fianl.... 。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。      1 p...

Java虚拟机栈

Java虚拟机栈

栈帧的内部结构 每个栈帧中存储着 1.局部变量表(Local Variables) 2.操作数栈(Operand Stack)(或表达式栈) 3.动态链接(Dynamic Linking)(或执行"运行时常量池"的方法引用)----深入理解Ja...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。