标签:
随着计算机革命的发展,“不安全”的编程方式已经逐渐成为编程代价高昂的主因之一。
初始化和清理,正是涉及安全的俩个问题。
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 垃圾回收器如何工作
标签:
原文地址:http://www.cnblogs.com/superzhao/p/4711485.html