Java编程思想之读书笔记系列三 --- 第四、五章 --- 控制执行流程、初始化与清理

这是Java编程思想之读书笔记系列第三篇,主要讲述第四五章的相关内容,尤其是第五章初始化与清理,个人感觉看下来还是受益匪浅的。好了,下面是具体内容:

  • Math.random()产生0和1之间(包括0,但不包括1)的一个double
  • C要求所有的变量都在一个块的开头定义,以便在创建这个块的时候,可以为那些变量分配空间;而在Java和C++中,则可在整个块的范围分散变量声明,在真正需要的地方才加以定义
  • 逗号操作符(只在for循环的控制表达式中使用)和逗号分隔符
  • 无穷循环:while(true)和for(;;)
  • goto是Java中的一个保留字
  • 标签是后面跟有冒号的标识符,在Java中,标签起作用的唯一地方刚好是迭代开始之前,即标签和迭代之间不能置入任何语句
  • 在Java中使用标签的唯一理由就是因为有循环嵌套存在,而且想从多层嵌套中break或continue
  • switch里是一个整数选择因子,只能是整型或者可以转成整型的数值类型,long和string是不能作用在switch上的
  • 方法重载的时候,参数顺序不同也足以区分
  • 基本数据类型的方法重载:
    • 如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升;char如果无法找到恰好接受char参数的方法,就会把char直接提升至int型
    • 如果传入的数据类型大于方法中声明的形式参数类型,必须进行显示的窄化转换
  • this,表示对当前调用方法的那个对象的引用
  • 可以用this调用一个构造器,但却不能调用两个,即在一个构造器里不能连续调用另外两个构造器;此外,必须将构造器调用置于最初始处,否则会报错
  • 在静态方法里传入一个对象的引用,通过这个对象就可以调用非静态方法和访问非静态数据成员;静态方法有全局函数的语义,而Java是禁止使用全局函数的,所以static方法是不是面向对象的,有待商榷
  • 垃圾回收器只知道释放那些经由new分配的内存,但是一个对象可能通过new以外的方式获得特殊的内存,此时垃圾回收器就不知道该如何释放这块特殊的内存,此时可以通过定义finalize()方法进行处理。工作原理如下:一旦垃圾回收器准备好释放对象占用的存储空间,会首先调用finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。这里有几点需要注意:(获得特殊内存的实例???
    • 对象可能不被垃圾回收
    • 垃圾回收不等于“析构”
    • 垃圾回收只与内存有关
  • finalize方法的需求只有一种特殊情况:通过某种创建对象以外的方式为对象分配了存储空间
  • 本地方法和局部对象(???)
    • 本地方法是一种在Java中调用非Java代码的方式,本地方法目前只支持C和C++
    • Java不允许创建局部对象(???),必须使用new创建
  • 垃圾回收器对于提高对象的创建速度有明显的效果
  • 通过垃圾回收器对对象重新排列,实现了一种高速的、有无限空间可供分配的堆模型
  • 垃圾回收器技术
    • 引用计数:如果对象之间存在循环引用,可能会出现“对象应该被回收,但是引用计数不为0”的情况。简单,但是速度很慢
    • 对任何“活”的对象,一定能最终追溯到其存活在堆栈或静态存储区之中的引用
  • 自适应的、分代的、停止-复制(stop-and-copy)、标记-清扫(mark-and-sweep)式垃圾回收器
    • 自适应:Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率降低,就切换到“标记-清扫”方式;同样,Java虚拟机会跟踪“标记-清扫”的效果,要是堆空间出现很多碎片,就会切换回“停止-复制”方式
    • 分代:内存分配以较大的“块”为单位,每个块都会用相应的代数(generation count)来记录它是否存活
    • 停止-复制:先暂停程序的运行,然后将所有存活的对象从当前堆复制到另一个堆,没有被复制的全部都是垃圾;新堆里的对象紧密排列
    • 标记-清扫:每当找到一个活的对象,设一个标记,全部标记工作完成时,开始清理动作
  • 即时编译器(Just-In-Time,JIT)
  • 惰性评估(lazy evaluation):即时编译器只要必要的时候才编译代码
  • 静态初始化只有在必要的时刻才会进行,而且只会初始化一次(在class对象首次加载的时候)
  • 构造器可以看成静态方法???
  • 对象创建过程(以Dog为例):P136
    • 当程序第一次新建Dog对象,或者程序调用Dog的静态属性或方法时,解释器会去查找Dog.class所在路径
    • 载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次
    • 当用new Dog()创建对象的时候,首先在堆上为Dog对象分配足够多的存储空间
    • 将分配的存储空间清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值
    • 执行所有出现于字段定义处的初始化动作
    • 执行构造器
  • Java允许将多个静态初始化动作组织成一个特殊的“静态子句”,也叫“静态块”,实例:
static   Cup cup1;
static   Cup cup2;
static {
     cup1 =  new   Cup( 1 );
     cup2 =  new   Cup( 2 );
}
Java中也有被称为实例初始化的类似语法,用来初始化每一个对象的非静态变量,实例:
Mug mug1;
Mug mug2;
{
     mug1 =  new   Mug( 1 );
     mug2 =  new   Mug( 2 );
}
与静态初始化子句相比,就是少了static关键字。这种语法对于匿名内部类的初始化是必要的,而且它也可以保证无论调用哪个显示构造器,某些操作都会发生。
  • Arrays.toString将产生一维数组的可打印版本
  • 数据定义和初始化:
    • 定义:
      • int[] a;
      • int a[];
    • 初始化:
      • Integer[] a = new Integer[4];(后续赋值)
      • Integer[] a = { new Integer(1), new Integer(2), 3,(最后一个逗号可选) };
      • Integer[] a = new Integer[]{ new Integer(1), new Integer(2), 3 };
  • 标准Java库中的类能够打印出有意义的内容,我们自己新建的类没有重写toString()方法的话,打印出的内容是:类名+@+多个十六进制数字
  • 可变参数列表:type...,实例比如:String...,Character...。可以使用任何类型的参数列表,包括基本类型;将0个参数传递给可变参数列表是可行的
  • getClass方法获得对应对象的类,并且在打印类时,可以看到该类类型的编码字符串。如果前导有[,表示该对象是紧随的类的数组。比如class [Ljava.lang.Character,表示该对象是Character类型的一个数组,Character类型对应的编码字符串是L
  • 应该总是在重载方法的一个版本上使用可变参数列表,或者压根不使用。下面这个实例里,g('a','b')会提示编译错误(character和int的共通性):
public   class TestGetClass {
 
     static   void f( float   i, String... args){
         System. out .println( "first" );
     }
      
     static   void f(String... args){
         System. out .println( "second" );
     }
      
     static   void g( float   i,  Character ... args){
         System. out .println( "first" );
     }
      
     static   void g( Character ... args){
         System. out .println( "second" );
     }
      
     public   static   void main(String[] args) {
         f(1, "a" );
         f( "a" , "b" );
          
         g(1, 'a' );
         g( 'a' , 'b' );
     }
 
}
  • 在你创建enum时,编译器会自动添加一些有用的特性。
    • toString()方法,以便可以很方便地显示某个enum实例的名字;
    • ordinal()方法,用来表示某个特定enum常量的声明顺序;
    • static values()方法,用来按照enum常量的声明顺序,产生由这些常量值构成的数组
  • enum也可以看成是一个类型,里面的每一个值就相当于该类型的一个实例,通过values()这一静态方法可以获得该类型的所有实例构成的数组,每个实例可以通过ordinal()方法获得对应的下标
  • 一个类加载的时候,有三个部分需要加载:
    • 静态变量
    • 静态方法
    • 静态初始化块
  • 对象实例创建:
    • 成员变量引入
    • 实例初始化块
    • 构造方法

以上就是第四五章的笔记内容,如有错误,敬请指出,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值