码迷,mamicode.com
首页 > 编程语言 > 详细

Java编程思想:第5章 初始化与清理

时间:2015-08-07 19:11:42      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

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

初始化和清理,正是涉及安全的俩个问题。

5.1 用构造器确保初始化

构造器名与类名相同,没有返回值

5.2 方法重载

构造器的重载与方法重载

5.2.1 区分重载的方法

参数列表的不同(不同顺序也是重载,但不建议这么做)

5.2.2 涉及基本类型的重载

  void print(char c){System.out.println("The character is "+c); }
    void print(byte b){System.out.println("The byte is "+b);}
    void print(short s){System.out.println("The short is "+s);}
    void print(int i){System.out.println("The int is "+i);}
    void print(long l){System.out.println("The long is "+l);}
    void print(float f){System.out.println("The float is "+f);}
    void print(double d){System.out.println("The double is "+d); }

1)如果直接传入数值,如 print(5)则5会被当做 int x = 5; print(x)去寻找最合适的print(int)

2)常量之外的类型会去寻找最合适的类型,没有同类型,但是有更大类型时会类型提升

3)char是一个特例,如果没有print(char)则char当做int,执行print(int)

4)需要用cast才能放入小类型的方法里

5.2.3 用返回值区分重载方法

void f(){}

int f(){return 1;}

这样是不可以的,因为很多时候我们不需要返回值,只是调用而已,那么我们会写:

f();这样是无法区分它是哪个方法的

5.3 默认构造器

如果类里没有构造器,编译器会帮你弄一个。

有了就不会帮你造一个了。

5.4 this关键字

可以用于指代调用对象方法时的“当前对象”,可以解决参数和域重名问题。

5.4.1 构造器中调用构造器

this(参数);

必须放于第一行,且最多只能调用一个。

5.4.2 static的含义

static方法就是没有this的方法,它属于类,不属于对象。

5.5 清理:最终处理和垃圾回收

Java垃圾回收器负责回收由new创建并且不再被使用的对象。

特殊情况是:如果一个对象以非new方式获得了一块内存区域,GC就不知道怎么回收这块特殊的内存。Java提供了finalize()方法,它的工作原理“假定”是这样的:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用finalize()方法, 并且在下一次垃圾回收动作发生时,才会真正回收对象内存。所以finalize()方法可以在垃圾回收时做一些重要的清理工作。

//此处疑惑感谢@Launcher的细心解答。

//---------------解答开始

也就是你有这样一个 class,伪码:

class A{

   IntPtr m_pBuffer;

    A(){

          m_pBuffer = malloc(1000);

     }

     void finalize(){

               free(_M_pBuffer);

       }
}

A 对象没有用 new ,而是使用 malloc 获得了一块特殊的内存区 m_pBuffer。

A a = new A(); // 还是使用 new 获得对象 A

但是对象 a 本身不用 new 获得的特殊内存区 m_pBuffer,不会被 GC 释放,所以你需要实现 finalize,在里面手动释放。

//---------------解答结束

 

这里有一个误区:

finalize() 与 C++中的析构函数(销毁对象时必须要用到这个函数)相同。

这是不正确的,C++中对象一定会被销毁,即析构函数一定被调用,而Java里的对象并不总是被垃圾回收。换句话说:

1)对象可能不被垃圾回收

2)垃圾回收不等于析构

5.5.1 finalize()用途何在

3)垃圾回收只与内存有关。

Java中无论对象是如何创建的,GC都会回收它的内存,对finalize()的需要限制到一种特殊情况:用了创建对象以外的方式,为对象分配了存储空间。

之所以要有finalize(),是由于在分配内存时可能采用了类似C语言的做法,这种情况主要发生在使用Java调用本地代码,如用C的malloc()函数系列来分配存储空间,所以需要在finalize()里调用本地代码,使用free()来释放这些内存。

所以不要过多使用finalize(),它不是进行普通清理工作的合适场所。

5.5.2 你必须实施清理

C++中所有对象都会被销毁。包括局部对象(在栈上创建的)和用new创建的对象(delete调用析构函数)。

Java不允许创建局部对象,必须使用new创建,也没有delete可用,释放对象内存只能由GC来完成,但是它并不保证一定去回收。如果希望在进行释放存储空间之外的清理操作,得明确在finalize()里使用,这等于析构了,但是没析构方便。

如果JVM没有面临内存耗尽的情况,它是不会浪费时间和资源去执行垃圾回收以恢复内存的。

5.5.3 终结条件

因为finalize()方法是在垃圾回收前执行的,所以复写finalize方法可以检测"逻辑上"的这个对象是否应该被终结。借此来发现程序中是否有缺陷。如:某对象代表了一个打开着的文件,而我们规定这种对象回收时必须为关闭状态。为了检测程序是否有缺陷,我们可以复写finalize方法检测是否打开状态,然后在某次finalize中查看是否存在问题,虽然finalize并不一定会调用,但是只要调用了一次我们就知道是否有问题,这才是关键。

我们可以利用System.gc()来建议做GC操作,但JVM有可能不听我们的。

5.5.4 垃圾回收器如何工作

 

Java编程思想:第5章 初始化与清理

标签:

原文地址:http://www.cnblogs.com/superzhao/p/4711485.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!