Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
问题:以下程序有什么问题?
public class SomethingIsWrong { public static void main(String[] args) { Rectangle myRect; myRect.width = 40; myRect.height = 50; System.out.println("myRect's area is " + myRect.area()); } }
答案:代码永远不会创建 Rectangle
对象。使用这个简单的程序,编译器会生成错误。但是,在更现实的情况下,myRect
可能会在一个位置初始化为 null
,比如在构造函数中,并在以后使用。在这种情况下,程序将编译得很好,但会在运行时生成 NullPointerException
。
问题:以下代码创建一个数组和一个字符串对象。代码执行后,对这些对象有多少引用?这两个对象是否有资格进行垃圾回收
... String[] students = new String[10]; String studentName = "Peter Smith"; students[0] = studentName; studentName = null; ...
答案:有一个对 students
数组的引用,该数组有一个对字符串 Peter Smith
的引用。这两个对象都没有资格进行垃圾回收。数组 students
不符合垃圾回收的条件,因为它有一个对象 studentName
的引用,即使该对象已被赋值 null
。对象 studentName
不符合条件,因为 students[0]
仍然引用它。
问题:程序如何销毁它创建的对象?
答案:程序不会显式销毁对象。程序可以将对象的所有引用设置为 null
,以使其符合垃圾回收的条件。但该程序实际上并没有销毁对象。
Exercise:修复问题 1 中所示的名为 SomethingIsWrong
的程序。
答案:参见 SomethingIsRight
:
public class SomethingIsRight { public static void main(String[] args) { Rectangle myRect = new Rectangle(); myRect.width = 40; myRect.height = 50; System.out.println("myRect's area is " + myRect.area()); } }
Exercise:给定以下类,名为 NumberHolder
,编写一些创建类实例的代码,初始化其两个成员变量,然后显示每个成员变量的值。
public class NumberHolder { public int anInt; public float aFloat; }
答案:参见 NumberHolderDisplay
:
public class NumberHolderDisplay { public static void main(String[] args) { NumberHolder aNumberHolder = new NumberHolder(); aNumberHolder.anInt = 1; aNumberHolder.aFloat = 2.3f; System.out.println(aNumberHolder.anInt); System.out.println(aNumberHolder.aFloat); } }