回顾Java编程思想篇(二)

4、销毁对象

Java中不需要程序员自己去销毁对象,这是为什么呢?

在C++中,对于变量及对象生命周期的维护占据了大量的编程时间,因为程序员需要知道变量存活的时间,以便在用完之后能把它销毁,不然会占满内存空间,阻塞程序。因此Java在设计时杜绝了这一问题。那么Java是怎么做的呢,看下面的介绍。

4.1、变量作用域

作用域决定了定义在其内的变量名的可见性和生命周期。在Java中作用域由花括号的位置决定。我们先看一下变量的作用域,例如:

package com.fei.test;

public class TestJava {
	public static void main(String[] args) {
		int x = 10;
		//仅x变量可用
		{
			int y =20;
			System.out.println("x = " + x);	
			x = 12;
			System.out.println("y = " + y);
			//x与y都可用
		}
		System.out.println("x = " + x);	
		//x可用,y超出了作用域范围	
	}
}

打印出的结果是:

x = 10
y = 20
x = 12

这里分为两个作用域,x定义在一级作用域里,y定义在二级作用域里。从结果可以看出二级作用域中对x变量重新赋值后,会覆盖上一级作用域的x变量的值。

Java中,在两个作用域的变量名称是不能一样的,比如:

		int x = 10;
		{
			int y =20;			
			int x = 12;//编译器会提示错误			
		}

因为Java设计者认为这样做会导致程序混乱,而在C++中这样是合法的。例如:

#include "stdafx.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	int x = 10;
	{
		int x = 12;
		cout<<"x = "<<x<<'\n';
		//这个作用域的x变量与上级作用域的x变量虽然名字相同,
		//但不是同一个变量。
	}
	cout<<"x = "<<x<<'\n';
	cin>>x;
	return 0;
}

打印出的结果是:

x = 12;

x = 10;

从结果看出,x变量在二级作用域重新定义后,变成另外一个x变量,它会替换一级作用域的x变量,但它的作用域只在二级作用域内有效,在一级作用域中定义的x变量在这样的情况下在二级作用域是起不了作用的。因此这样很容易搞不清楚x变量的使用情况,Java在设计时避免了这一情况。

4.2 对象作用域

下面看一下对象的作用域

Java对象与基本类型的变量有不一样的生命周期。当用new创建一个对象后,它可以存活于作用域之外。先看一段代码:

package com.fei.test;

public class TestJava {

	public static void main(String[] args) {
		String s1 = new String("abc");
		{
			System.out.println("s1 = " + s1); //s1可用
			String s2 = new String("efg");
			System.out.println("s2 = " + s2); //s2可用
		}	
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2); //编译错误,s2超出了其作用域。
	}
}

从代码看起来,s1对象s2对象好像和变量是一样的生命周期,其实不然,这里只是指的s1引用和s2引用的生命周期。s2引用在二级作用域终点就消失了,因此在一级作用域里就不可用了。但是,s2指向的String对象仍然存在于内存中。如果要在其他作用域使用s2指向的对象怎么办呢?那么可以使用传递和复制对象引用的方式来使用对象。

这样会出现一个问题,每次新建的对象会一直保留在内存中,不是要把内存占满吗?不用担心,Java使用了一个叫做垃圾回收机制的功能,用来监视用new创建的所有对象,一旦发现那些不会再被引用的对象,便释放这些对象的内存空间,以便供其他新的对象使用。

因此新建的对象有两个去处,一个是通过传递和复制引用的方式供别的作用域使用,一个是被垃圾回收器销毁。 

posted @ 2010-02-03 10:19  FigoYu  阅读(252)  评论(0编辑  收藏  举报