Thinking in Java学习扎记(七)

转载 2004年09月04日 18:05:00
清理:终结与垃圾回收
        这里要明白这么几点
        1、垃圾回收器只能回收由new产生的对象,如果你使用或产生了非new产生的对象,垃圾回收器是不知道如何把他清理掉的 。这个时候就要使用到finalize()。
        2、垃圾回收器的运做方式是这样的,当垃圾回收器打算开始释放你的对象所占用的资源时,会先调用finalize(),并且在下一次垃圾回收动作放生的时候才回收该对象所占用的资源,如果使用finalize(),他便会让你得以在垃圾回收的时候执行你自己的清理动作
        3、finalize()是不会在对象销毁的时候自动唤起的。假设有一个对象在产生的过程中将自己绘制在屏幕之上。你要是没有手动的把他清理掉,那么他永远会在那里,而如果你将清理屏幕的功能放在finalize()之中,那么当这个对象被垃圾回收器回收之前,他在屏幕上的影象会先被清除
        4、你的对象永远可能都不会被回收,因为你的程序并没有把系统资源占用到需要垃圾回收器出马的状态,你所占用的系统资源会在程序结束运行的时候全部释放,那么你就不用付出垃圾回收器运行的额外系统开支。
        finalize()存在是为了什么?
         要知道,finalize()不是用于一般的清理工作,垃圾回收器回清理那些使用new产生的对象,而那些非常规方法(c/c++原生函数)产生对象才会需要
 finalize()来进行清理工作。既然这样,我们就不应该大量的使用finalize(),因为他不是摆放常规清理动作的执行场所。
        你必须执行清理动作
          那么那里才是正常清理动作的执行场所呢?
          在c++中,当对象以stack中创建得时候,那么有一个叫析构的函数会自动的在该对象产生地点所在的大括号范围结束前自动调用,如果这个对象是以new的方式从heap中创建的话,那么就必须调用delete运算符才能清理对象。而java不允许对象从stack中创建,你一定得用new从heap中创建对象才行,但是java并没有delete运算符,而是靠的是垃圾回收器来清理对象,所以,我们可以说,既然java中有了垃圾回收器,也就不需要析构函数。但是垃圾回收器毕竟不是析构函数,他无法代替析构函数的作用。如果你除了释放空间之外还要执行其他的清理动作,那么你就要自行调用类似于析构函数的函数
        
死亡条件
          只要程序不依靠于调用finalize(),那么这个函数还有一个用途,就是对对象的死亡条件的检查。
          那么,什么是死亡条件呢?在对象被清理的时候,该对象一定是要处于某种状态下才能会被正常的清理,也就是假如有一个数据流已经不再使用了,需要清理掉,那么你再清理之前,先要被关闭掉,这就是一种死亡条件
           
 class myclass
            {
             boolean b = false;
             myclass(boolean b)
             {
              this.b=b;
             }
             void death()
             {
              b=false;
             }
             public void finalize()
             {
              if(b)         
//死亡条件就是b必须要是false
               System.out.println("Error : b is true ,class can't  be clean");
              else
               System.out.println("OK ! CleanUp");
             }
            }
            class test
            {
             public static void main(String args[])
             {
              myclass  mc = new myclass(true);
              mc.death();
              new myclass(true);
              System.gc();      
//System.gc()被用来强迫终结动作的发生,不过即使没有使用他,只要你能把系统资源占用到必须垃圾回收器出马的时候,finalize()还是会被执行的
             }
            }
        垃圾回收器的运做方式
          学过程序的人应该都知道,从heap中创建对象(基本数据类型除外)的做法,会大幅度的影响系统的速度,然而垃圾回收器的竟然能大幅度的提高从heap中创建对象的效率,你也许会很惊奇,垃圾回收器的储存空间的释放竟然能影响到储存空间的分配,还有更惊奇的,这种从heap中创建对象的方式的速度已经逼近其他语言从stack中创建的速度了!
          为什么会这样子呢?想象一下,一个倒霉的家伙(对象)站一个公交车(c++的heap)上,而其他的人都有座位,他需要不停的环视车内,希望能有没人做的座位(高的代价),一单某个人(对象)离开座位(被释放),他就会冲上去坐好。而在java的jvm中,公交车的座位变成了传送带,当有空的座位的时候,后面的人补上前面的座位,依次类推,而那个倒霉的人只要直接的前往最后一个被置空的座位就行了,而不需要他在不停的环视周围。垃圾回收器会重新排列heap中的所有对象,使他们更紧密的排列在一起,这样就能使heap指针移至更靠近传送带前段的位置,避免内存分页置换动作,效率大大提高。
          gc为了取得更快的垃圾回收速度,于是他会在static和stack中查找每个对象的句柄是否指向一个heap来判断该对象是否被引用,是否该清理,清理之后会把更改的句柄重新映射排列。因为gc的这种特殊性,当gc启动的时候,执行中的程序会暂时停止。
     
成员初始化
       在java中,class的基本数据类型的数据成员变量会被系统自动初始化,而当变量被定义在函数之中的时候,他是不会被系统自动初始化的
         
 class test
          {
           byte b;
           char c;
           short s;
           int i;
           long l;
           float f;
           double d;
           boolean bl;
           void go()
           {
            int ii;
           
 //System.out.println(ii);当变量被定义在函数之中的时候,他是不会被系统自动初始化的
            ii=10;
            System.out.println(ii);
            System.out.print(
                  "byte : "+b+"/n"+
                  "char : "+c+"/n"+
                  "short : "+s+"/n"+
                  "int : "+i+"/n"+
                  "long : "+l+"/n"+
                  "float : "+f+"/n"+
                  "double : "+d+"/n"+
                  "boolean : "+bl+"/n");
           }
           public static void main(String args[])
           {
            test t = new test();
            t.go();
           }
          }
          结果
          
10
          byte : 0
          char :      char的值为0,显示空白
          short : 0
          int : 0
          long : 0
          float : 0.0
          double : 0.0
          boolean : false
     
指定初值
       怎么样指定初指,这个我想我不用再写了吧~这个大家肯定知道
     以构造函数进行初始化动作
       构造函数可以用来执行初始化动作,因而你有更大的弹性,但是构造函数的初始化动作是发生再自动初始化之后的
      
 class test
       {
        int i;
        test()
        {
         i=10;
        }
       }
       那么,i先会被自动初始化为0,然后才会被构造函数初始化为10,就连定义变量的时候就给定初始值的时候也是一样的,这点需要注意
       初始化次序
         变量的初始化顺序取决于class中的定义变量的次序,变量也许会散落各处,穿插在函数之中,但是所有的变量一定在任何函数,哪怕是构造函数被调用之前完成初始化
      
 静态数据的初始化
         static的基本数据类型的数据初始化情况和non-static的基本数据类型没什么不同的,但是假如他是某个对象的句柄,那么初始值就是null。static的初始化动作只会在必要的时候发生,如果你没有产生class对象,也没有调用静态的数据,则static的数据永远不会被初始化。static的初始化只会发生在第一个static的访问动作发生的时候,自此之后,static对象便不会再被初始化
         如果static并没有在对象生成的时候初始化,那么变量的初始化顺序就变为static、non-static、method
       
static明确初始化
         java中允许你将多个static的变量组织起来,放在static 块中
        
 static
         {
          int i =10;
          byte b= 20;
         }
         当你首次产生class对象,或者首次调用该类的static成员,static 块就被初始化
       
non-static实体初始化动作
         java中也为非静态的变量初始化提供了类似于static的方法
         
{
          int i=10;
          byte b=10;
         }
         如果我们想产生无名的内隐类,这个方法是必须的(第8章会讲到)

《Thinking in Java》读书笔记(不断更新中)

概述春节在家乡,家里的电脑都是我上大学时淘汰的,要么运行不起来AS,要么连接不上手机,要么编译不了程序,这Android是写不了了。 记得前几天写插件的时候,用过Intellij IDEA,感觉很流...
  • zxt0601
  • zxt0601
  • 2017年01月31日 11:29
  • 970

扎金花大小比较算法(Java版)

扎金花大小比较算法,实现算法特点: 1)采用面向对象方式实现,分别构造牌面值的对象(枚举)、牌的花色对象(枚举)、玩家三张牌的类型(枚举,如豹子、同花顺等)、一张扑克牌对应的对象(一张牌有一个牌面值属...
  • dobuy
  • dobuy
  • 2014年06月17日 00:10
  • 4831

《Thinking in Java》读后总结与感想

作为Java界的四大名著之一《Thinking in Java》一直备受推崇,我很早就知道了这本书,当时只是初涉Java,粗略的翻了翻之后觉得看起来这本书讲的比较深就没有再去碰它,后来Java基础学完...
  • qq_28899635
  • qq_28899635
  • 2017年01月16日 09:47
  • 478

JAVA学习练习(扎金花与21点)

目前转行学习JAVA。记得N年学过C++,接触JAVA后感觉上手比较容易。学习半月熟练使用循环、判断,自行看书了解JAVA类的使用,并尝试用类完成编程。大概完成了老师题目,纯新一个,类和方法用得很混乱...
  • Heavy_ANT
  • Heavy_ANT
  • 2015年04月27日 19:56
  • 1206

Thinking In Java笔记(第八章 多态)

第八章 多态    在面向对象的程序设计语言中,多态是继抽象和技能之后的第三种基本特征。多态不但能够改善代码的组织结构和可读性,还能够创建可扩展的程序。     多态的作用是用来消除类型之间的耦合关系...
  • Jing_Unique_Da
  • Jing_Unique_Da
  • 2015年06月10日 10:19
  • 1487

Thinking in Java 源码的获取以及编译问题

《Java编程思想》的源代码的获取、编译过程,以及编译中碰到的错误。还有Ant程序的获取和配置。...
  • pdcxs007
  • pdcxs007
  • 2014年01月09日 10:05
  • 3199

Thinking in Java:容器深入研究

1.虚线框表示Abstract类,图中大量的类的名字都是以Abstract开头的,它们只是部分实现了特定接口的工具,因此创建时可以选择从Abstract继承。Collections中的实用方法:挑几个...
  • zhangqix
  • zhangqix
  • 2016年04月01日 19:48
  • 749

第21章 并发 ——《Thinking in Java》学习笔记

说道并发,就有种异常高大上的感觉,好像比那些顺序编程有种不可明辨的优越感一样,是的,并发的确更深奥,而且现在全世界都离不开并发程序。 但是什么是并发?并发能做什么?并发如何实现? --------...
  • u010635780
  • u010635780
  • 2014年08月12日 19:40
  • 753

Thinking in java学习笔记-并发(一)

一、线程和进程 进程:进程是运行在它自己的地址空间内的自包容的程序 线程:线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行...
  • linsawako
  • linsawako
  • 2016年11月20日 18:30
  • 491

炸金花绝对大小计算、比较及排序算法(Java),包含花色参与和不参与大小比较

昨日忽生兴趣,想起同事正在玩的一个炸金花游戏,见他们讨论略有激烈,想来蛮有趣,于是自己也写来玩玩。 因有要一次产生很多副牌的需求(可能上1000),要对所有的玩家进行一个排序,因此考虑一个能得到每幅...
  • zyzhehe
  • zyzhehe
  • 2016年12月24日 14:09
  • 2291
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Thinking in Java学习扎记(七)
举报原因:
原因补充:

(最多只允许输入30个字)