初始化与清理

随着计算机革命的发展,“不安全”的编程方式已逐渐成为编程代价的高昂的主因之一。

用构造器确保初始化

  1. 构造器是一种特殊的方法,采用与类名相同的名称。
  2. 构造器没有返回值。返回空void和没有返回值是不一样的
  3. 不接受任何参数的构造器叫默认构造器
  4. Book b = new Book(); 创建对象为对象在堆上分配了空间,并调用构造器初始化了对象。从概念上讲,“初始化”和“创建”是彼此对立的,但在Java中“初始化”和“创建”是捆绑在一起的,不能分离。

方法重载

  1. 方法重载,一个类中出现方法名相同的方法。
  2. 构造器也是一种方法,所以构造器也是可以重载的。
  • 区分重载方法
    通过方法的参数列表,每个重载方法都有一个独一无二的参数列表。
  1. 参数列表的参数类型
  2. 参数列表的参数顺序(参数类型的顺序),但一般情况下不应该那么做,原因是难以区分。
  • 涉及基本类型的重载
  1. 基本类型能从一个“较小”的类型自动提升至一个“较大”的类型。首先找最佳的方法,找不到会被提升,bety->short->int , short->int , char->int
  2. 如果传入的参数“大于”方法的参数类型,需要显示的转型,否则编译器不让编译过。
  • 以返回值区分重载方法
    如果方法有返回值,但是不需要返回值时可能没办法区分,所以不能以返回值来区分重载方法。

默认构造器

没有任何参数的构造器叫默认构造器。在一个类中,如果没有写这个类的任何构造器,那么编译器就会为这个类添加一个默认构造器。但是只要写出一个构造器,不管写的是无参的还是有参的构造器,编译器都不会在为这个类添加默认构造器。

成员初始化

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

  • 类的成员数据
  1. 基本数据类型被默认初始化为0,char为0,即显示的是空格。
  2. 非基本数据类型如果不将其初始化,此引用就会获得一个特殊的值null。

以上称为自动初始化

  • 指定初始化
  1. 在定义类的成员变量的地方就赋值。
  2. 甚至可以通过调用某个方法来提供初始值 int i = f(); 基本类型和非基本类型都可以。

构造器初始化

可以用构造器来初始化。在运行时刻,可以调用方法或执行某些动作来确定初始值。但这些操作无法阻止自动初始化的进行。

public class Counter{
	int i ;
	Counter(){
    	i = 7 ;
	}
}

由于自动初始化,i先为0,然后调用构造器i才变为7。即自动初始化在构造器调用这前完成。对基本数据累心个对象引用都是成立的 。

初始化的顺序

  1. 在类的内部,普通成员字段的定义顺序决定了自动初始化的顺序。
  2. 在类的内部,静态成员字段的定义顺序决定了自动初始化的顺序。静态成员字段的自动初始化得到的默认值和普通成员字段得到的默认值一样(基本类型和对象引用都一样)

普通成员字段和静态成员字段初始化的区别

  1. 静态成员字段只有在第一次访问这个类的时候才会得到初始化,只执行一次
  2. 普通成员字段在每次调用类的构造器的时候都会初始化一次
  3. 类中,普通成员字段和静态成员字段共存时,先是所有静态成员得到初始化(顺序按定义的顺讯)完成后再到普通成员字段(顺序按定义的顺讯)初始化。
    4.类中可以定义代码块。例子
class Block{
    int a ;
    static int b ;
	// 静态块
	static{
	b = 17 ;
	}
	// 非静态块
	{
	a = 7;
	}
}

静态块和非静态块初始化的顺讯与普通成员字段和静态成员字段共存时初始化的顺讯一样。
普通成员字段、静态成员字段、静态块和非静态块共存,初始化顺序是静态(字段或块,不管是字段还是块,都是按定义顺序)到非静态(字段或块,不管是字段还是块,都是按定义顺序)。

this 与 static

  • this
  1. this表示对“调用方法的那个对象”的引用。即代表的是对象的引用而不是对象本身。
  2. this的用法和其他对象引用的用法没有什么不同。但this只能在方法中使用。
  3. this可以在构造器方法中使用。如果在构造器内部使用this调用的是另外一个构造器(例:this();或 this(参数列表);),则这句代码一定要出现在构造器方法体的第一行。
  • static
    我们了解了this,this描述的是对象。而static描述的是类。static成员字段和static方法在没有创建这个类的任何对象的情况下就可以被访问,即已经“存在”。static定义字段只能是类的成员字段,不能是局部变量。在静态方法中不能使用非静态字段。
    我们在一切都是对象中说到,每个对象都有用来存储其字段的空间。static字段在没有创建对象可以直接通过类来访问,所以static字段的存储空间不依赖对象,即不论创建了这给类的所少个对象,所有的对象在类中被定义为static的字段都是指向同一个空间,所以有一改全改的效果。static字段对每个类来说都只有一份存储空间,而非static字段则是对每个对象都有一个存储空间

清理

  • 垃圾回收器
  1. 垃圾回收器只能回收通过普通方式new的方法创建出来的方法。(即还有其他方法创建对象)
  2. 对于非普通方式创建出来的对象的回收。Java允许在类中定义一个fianlize()方法。它的工作原理“假定”为:一旦垃圾回收器准备好释放对象占用的存书空间,将首先调用其fianlize方法,并在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。所以要是打算用fianlize,就能在垃圾回收是个做一些重要的清理工作。但是fianlize方法不像c++中的析构函数,c++中,对象一定会被销毁,即析构函数一定会被调用。而Java里的对象却并非总是被垃圾回收。
  3. 对像可能不被垃圾回收。(内存还足够的时候,因为使用垃圾回收也需要开销)
  4. 垃圾回收并不等于“析构”。c++中对象一定会被销毁,所以析构函数一定会被调用。而Java中对像不一定被回收,所以fianlize不一定被调用。
  5. 垃圾回收只与内存有关。所以对于垃圾回收有关的方法(尤其是fianlize),他们也必须和内存有关。
  • fianllize的用途
    由于垃圾回收器只回收通过new创建出来的对象,所以可以在fianlize作用调用其他方法来释放非new方式创建出来的对象。fianlize方法还可以用来验证对象终结。

  • 垃圾回收器的工作原理
    先了解引用计数原理,这是一种简单但速度非常慢的垃圾回收技术。每个对象都含有引用计数器,当有引用连接至对象时,引用计数+1。当引用计数离开作用域或被置为null时,引用计数-1。垃圾回收器会在含有全部对象的列表上遍历,当发现某个对象的引用计数为0,就释放其占据的内存(但是,引用计数模式进场会在计数值变为0是立即释放对象)。引用计数有两个缺点:

  1. 引用计数的开销不大,但这项开销在整个生命周期中将持续发生。
  2. 如果对象间存在循环引用,可能会出现“对象应该被回收,但引用计数却不为0”的情况。

更快的垃圾回收器并非基于引用计数计数。他们依据的思想是:对任何“活”的对象,一定能最终最终追溯到其在堆栈或静态存储区之中的引用。这个引用链条可能穿在数个对像层次。由此,如果从堆栈和静态存储区开始,遍历所有引用,就可能找到所有“活”的对象。对象发现的引用,必须追踪它所有的引用,然后是此对象包含的所有引用。如果反复进行,直到“根源于堆栈和静态存储区的引用”所形成的网络全部被访问为止。

在这种方式下,Java虚拟机采用了一种自适应的垃圾回收技术。至于怎么找到所有活的对象取决于不同的Java虚拟机。有一种做法叫停止-复制。即先停止程序的允许(所以它不属于后台回收模式),然后将所有存活的对象从当前复制到另一个堆,没有被复制的全部是垃圾。

对于“复制式回收”而言,效率会降低,这个原因有两个原因。

  1. 首先,得有两个个堆,所以需要比实际多出一倍的空间。
  2. 当程序进入稳定状态之后,可能只会产生少量的垃圾,甚至没有垃圾。这种情况下,复制式回收器任将所有内存自一处复制到另一处。这样就很浪费。所以一些虚拟机会进行检查:要是没有新的垃圾产生,就会转换到另外一种工作模式,标记-清扫模式。

标记-清扫模式依据的思想同样是从堆栈和静态存储区出发,遍历所有的引用,进而找出所有存活的对象。每当找到一个存活对象,就会给对象一个标记,这个过程中不会回收任何对象。是有全部标记工作完成的时候,清理动作才会开始。在清扫过程中,没有标记的对像将被释放,不会发生任何复制动作,所以剩下的空间也不是连续的,垃圾回收器要是希望得到连续空间的话,就需要重新整理剩下的对象。

Java虚拟机会进行监视,如果对象都很稳定,垃圾回收器的效率低的话,就切换到“标记-清楚”方式:同样,Java虚拟机会跟踪“标记-清扫”的效果,要是堆空间出现很多碎片,就会切换到“停止-复制”方式,这就是自适应技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值