【Java练习题】Java 程序的输出 | 第十套

举报
海拥 发表于 2022/03/30 23:10:23 2022/03/30
【摘要】 难度级别: 中级在 Java 中,对象销毁由垃圾收集器模块负责,没有任何引用的对象有资格进行垃圾收集。下面是一些关于垃圾收集的重要输出问题。 程序 程序一预测以下 Java 程序的输出:public class Test{ public static void main(String[] args) throws InterruptedException { String str = ne...

难度级别: 中级
在 Java 中,对象销毁由垃圾收集器模块负责,没有任何引用的对象有资格进行垃圾收集。下面是一些关于垃圾收集的重要输出问题。

程序

程序一

预测以下 Java 程序的输出:

public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		String str = new String("Haiyong");
			
		// 使 str 符合 gc 的条件
		str = null;
			
		// 调用垃圾收集器
		System.gc();
			
		// 等待 gc 完成
		Thread.sleep(1000);
	
		System.out.println("end of main");
	}

	@Override
	protected void finalize()
	{
		System.out.println("调用的finalize方法");
	}
}

点此跳转到答案

程序二

public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		Test t = new Test();			
		// 使 t 有资格进行垃圾收集
		t = null;			
		// 调用垃圾收集器
		System.gc();			
		// 等待 gc 完成
		Thread.sleep(1000);	
		System.out.println("end main");
	}
	@Override
	protected void finalize()
	{
		System.out.println("调用的finalize方法");
		System.out.println(10/0);
	}	
}

点此跳转到答案

程序三

public class Test
{
	static Test t ;	
	static int count =0;	
	public static void main(String[] args) throws InterruptedException
	{
		Test t1 = new Test();			
		// 使 t1 有资格进行垃圾收集
		t1 = null; // line 12			
		// 调用垃圾收集器
		System.gc(); // line 15			
		// 等待 gc 完成
		Thread.sleep(1000);	
		// 使 t 有资格进行垃圾收集
		t = null; // line 21			
		// 调用垃圾收集器
		System.gc(); // line 24	
		// 等待 gc 完成
		Thread.sleep(1000);			
		System.out.println("调用finalize方法 "+count+" 次");		
	}	
	@Override
	protected void finalize()
	{
		count++;		
		t = this; // line 38			
	}	
}

点此跳转到答案

程序四

public class Test
{
	public static void main(String[] args)
	{
		// 此行之后有多少对象符合垃圾回收条件?
		m1(); // Line 5
	}

	static void m1()
	{
		Test t1 = new Test();
		Test t2 = new Test();
	}
}

点此跳转到答案

程序五

public class Test
{
	public static void main(String [] args)
	{
		Test t1 = new Test();
		Test t2 = m1(t1); // line 6
		Test t3 = new Test();
		t2 = t3; // line 8
		
	}	
	static Test m1(Test temp)
	{
		temp = new Test();
		return temp;
	}
}

点此跳转到答案


文章后半部分是程序的输出及解析

60f7e8b025fa0.jpeg

image.png


输出及解析

程序一输出

输出

end of main

解释

我们知道在销毁对象之前,垃圾收集器会在对象上调用finalize()方法。但在这里,诀窍是 str 是 String 类对象,而不是 Test 类。因此,在 str 上调用 String 类的 finalize() 方法(如果在 String 类中重写)。如果一个类没有覆盖 finalize 方法,那么默认情况下会调用 Object 类的 finalize() 方法。

程序二输出

输出

调用finalize方法
end main

说明

当垃圾收集器对对象调用 finalize() 方法时,它会忽略该方法中引发的所有异常,程序将正常终止。

程序三输出

输出

调用finalize方法 1

说明

执行第 12 行后,t1 可以进行垃圾回收。所以当我们在第 15 行调用垃圾收集器时,垃圾收集器会在销毁它之前调用 t1 上的 finalize() 方法。但是在 finalize 方法中,在第 38 行,我们再次通过 t 引用同一个对象,因此在执行第 38 行后,该对象不再符合垃圾回收条件。因此,垃圾收集器不会销毁对象。

现在再次在第 21 行,我们再次使同一对象有资格进行垃圾回收。在这里,我们要明确有关一个事实有关垃圾收集器,即它会调用finalize()方法的特定对象恰好在一个时间。由于在这个对象上已经调用了 finalize() 方法,所以现在垃圾收集器将销毁它,而无需再次调用 finalize() 方法。

程序四答案

问题:
执行第 5 行后,有多少对象符合垃圾回收条件?

回答 :

2

说明

由于 t1 和 t2 是 m1() 方法的本地对象,因此除非返回任何一个,否则在方法完成后它们有资格进行垃圾收集。

程序五答案

问题:
执行第 8 行后,有多少对象符合垃圾回收条件?

回答 :

1

说明:

到第 8 行执行时,唯一没有引用的对象是第 6 行生成的对象。请记住,“Java 严格按值传递”,因此引用变量 t1 不受 m1( ) 方法。我们可以使用 finalize() 方法检查它。finalize()方法中的语句“System.out.println(this.hashcode())”打印调用finalize()方法的对象hashcode值,然后将该值与main方法中创建的其他对象hashcode值进行比较.


以上就是本篇文章的所有内容了

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。