文档章节

JAVA编程思想——第五章.初始化与清理

leooooo
 leooooo
发布于 2016/11/23 21:45
字数 2142
阅读 51
收藏 0
点赞 0
评论 0

    工作三年多了,做过不少的项目,越到最近越深深地感觉到自己的基础薄弱,所以最近买了《java编程思想》。希望通过这次的学习能够使自己有所收获。

    这也是我第一篇博客,以往只是看而没有自己写过,这次着重记录书本上习题的解答。

    5.1 用构造器确保初始化

    练习1:创建一个类,它包含一个未初始化的String引用。验证该引用被java初始化成了null。

package chapter5;

public class Session1 {

	/**
	 * 未初始化的变量会自动初始化为null
	 */
	String a;
	
    public static void main(String[] args) {
		Session1 session1 = new Session1();
		System.out.println(session1.a);
        //“null”
	}
}

    练习2:创建一个类,它包含一个在定义是就被初始化了的String域,以及另一个通过构造器初始化的String域。这两种方式有何差异?

package chapter5;

public class Session1 {
	
	/**
	 * 会先初始化类中的变量
	 */
	String b = "hello";
	String c;
	
	public Session1() {
		System.out.println(b);
		/**
		 * 后进行c的初始化
		 */
		c = "world";
	}
	
	public static void main(String[] args) {
		Session1 session1 = new Session1();
        //在类初始化前会先初始化类中的变量
        //“hello”
	}
}

    5.3 默认构造器

    练习3:创建一个带默认构造器(即无参构造器)的类,在构造器中打印一条消息。为这个类创建一个对象。

package chapter5;

public class Session2 {

	public Session2() {
		System.out.println("我是默认构造器");
	}
	
    public static void main(String[] args) {
		Session2 session2 = new Session2();
        //“我是默认构造器”
	}
	
}

    练习4:为前一个联系中的类添加一个重载构造器,令其接受一个字符串参数,并在构造器中把你自己的消息和接收参的参数一起打印出来。

package chapter5;

public class Session2 {

	public Session2() {
		System.out.println("我是默认构造器");
	}
	
	public Session2(String arg) {
		this();
		System.out.println("我是重载有参构造器,我接收的参数为:"+arg);
	}
	
	public static void main(String[] args) {
		Session2 session2 = new Session2("hello world");
        //“我是默认构造器”
        //“我是重载有参构造器,我接收的参数为:hello world”
	}
	
}

    练习5:创建一个名为Dog的类,它具有重载的bark()方法。此方法应根据不同的基本数据类型进行重载,并根据被调用的版本,打印出不同类型的狗吠(barking)、咆哮(howling)等信息。编写main()来调用所有不同版本的方法。

    

package chapter5;

public class Dog {

	
	void bark(String a){
		System.out.println("barking:狗吠");
	}
	
	void bark(Integer i){
		System.out.println("howling:咆哮");
	}
	
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.bark("barking");
		dog.bark(1);
        //barking:狗吠
        //howling:咆哮
	}
}

    练习6:修改前一个练习的程序,让两个重载方法各自接受两个类型不同的参数,但二者顺序相反。验证其是否工作。

package chapter5;

public class Dog {
	
	/**
	 * 参数顺序不同也可以重载
	 * @param i
	 * @param a
	 */
	void bark(Integer i,String a){
		System.out.println("barking:狗吠");
	}
	void bark(String a,Integer i){
		System.out.println("howling:咆哮");
	}
	
	public static void main(String[] args) {
		Dog dog = new Dog();
		dog.bark(1,"barking");
		dog.bark("barking",1);
        //barking:狗吠
        //howling:咆哮
	}
}

    练习7:创建一个没有构造器的类,并在main()中创建其对象,用以验证编译器是否真的自动加入了默认构造器。

package chapter5;

public class Session7 {
	
	public static void main(String[] args) {
		Session7 session7 = new Session7();
	}

}

    5.4 this关键字

    练习8:编写具有两个方法的类,在第一个方法内调用第二个方法两次:第一次调用时不使用this关键字,第二次调用时使用this关键字——这里只是为了验证它是起作用的,你不应该在实践中使用这种方式。

package chapter5;

public class TestThis {

	private void method1(){
		method2();
		/**
		 * this指当前对象的引用
		 */
		this.method2();
	}
	
	private void method2(){
		System.out.println("方法二");
	}
	
	public static void main(String[] args) {
		TestThis testThis = new TestThis();
		testThis.method1();
        //方法二
        //方法二
	}
}

    练习9:编写具有两个(重载)构造器的类,并在第一个构造器中通过this调用第二个构造器。

package chapter5;

public class Session4 {

	public Session4() {
		this("通过this调用有参构造器");
		System.out.println("无参构造器");
	}
	
	public Session4(String arg) {
		System.out.println(arg);
	}
	
	public static void main(String[] args) {
		Session4 session4 = new Session4();
        //通过this调用有参构造器
        //无参构造器
	}
	
}

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

    练习10:编写具有finalize()方法的类,并在方法中打印消息。在main()中为该类创建一个对象。试解释这个程序的行为。

package chapter5;

public class TestFinalize {
	
	@Override
	protected void finalize() throws Throwable {
		System.out.println("回收前执行的方法");
	}
	
	public static void main(String[] args) {
		TestFinalize finalize = new TestFinalize();
	}

}

    finalize()方法不一定会执行。

    练习11:修改前一个程序,让你的finalize()总会被调用。

package chapter5;

public class TestFinalize {
	
	@Override
	protected void finalize() throws Throwable {
		System.out.println("回收前执行的方法");
	}
	
	public static void main(String[] args) {
		TestFinalize finalize = new TestFinalize();
		finalize = null;
		System.gc();
        //回收前执行的方法
	}

}

    练习12:编写名为Tank的类,此类的状态可以使“满的”或“空的”。其终结条件是:对象被清理时必须处于空状态。编写finalize()以检验终结条件是否成立。在main()中测试Tank可能发生的几种使用方式。

package chapter5;

public class Tank {

	private boolean full = true;
	
	@Override
	protected void finalize() throws Throwable {
		if(!full){
			System.out.println("空了,不要了");
		}
	}
	
	public static void main(String[] args) {
		Tank t = new Tank();
		t = null;
		System.gc();
        //此时状态是“满的”所以回收时不会执行输出
	}
	
}
package chapter5;

public class Tank {

	private boolean full = true;
	
	@Override
	protected void finalize() throws Throwable {
		if(!full){
			System.out.println("空了,不要了");
		}
	}
	
	public static void main(String[] args) {
		Tank t = new Tank();
		t.full = false;
		t = null;
		System.gc();
        //状态是“空的”
        //回收时会输出
        //空了,不要了
	}
	
}

    5.7 初始化顺序

    练习14:编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另一个在静态块中初始化。现在加入一个静态方法用以打印出两个字段值。请证明他们都会在被使用之前完成初始化动作。

package chapter5;

public class Session7 {
	
	
	static String a = "hello world";
	
	static String b;
	
	static {
		b = "hello world 2";
	}
	
	public static void main(String[] args) {
		System.out.println(Session7.a);
		System.out.println(Session7.b);
        //hello world
        //hello world 2
	}

}

    练习15:编写一个含有字符串域的类,并采用实例初始化方式进行初始化。

package chapter5;


public class Session71 {

	String a;
	
	{
		a = "hello world";
	}
	
	public static void main(String[] args) {
		Session71 session71 = new Session71();
		System.out.println(session71.a);
        //hello world
	}
}

    5.8 数组初始化

    练习16:创建一个String对象数组,并为每一个元素都赋值一个String。用for循环来打印该数组。

package chapter5;

public class Session8 {

	String[] strs = {"h","e","l","l","o"};
	
	public static void main(String[] args) {
		Session8 session8 = new Session8();
		for (String string : session8.strs) {
			System.out.print(string);
		}
        //hello
	}
	
}

    练习17:创建一个类,他有一个接受一个String参数的构造器。在构造阶段,打印该参数。创建一个该类的对象引用数组,但是不实际去创建对象赋值给该数组。当运行程序时,请注意来自对该构造器的调用中的初始化消息是否打印了出来。

package chapter5;

public class Session81 {

	
	public Session81(String a) {
		System.out.println(a);
	}
	
	
	public static void main(String[] args) {
		Session81[] sss = new Session81[]{};
		//不会进行打印输出
	}
}

    练习18:通过创建对象赋值给引用数组,从而完成前一个练习。

package chapter5;

public class Session81 {

	
	public Session81(String a) {
		System.out.println(a);
	}
	
	
	public static void main(String[] args) {
		Session81[] sss = new Session81[]{new Session81("1"),new Session81("2")};
		//1
		//2
	}
}

    练习19:写一个类,他接受一个可变参数的String数组。验证你可以向该方法传递一个用逗号分隔的String列表,或是一个String[]。

package chapter5;

public class Session82 {

	public Session82(String ...a) {
		for (String string : a) {
			System.out.println(string);
		}
	}
	
	public static void main(String[] args) {
		Session82 session82 = new Session82("a","b");
		
		Session82 session821 = new Session82(new String[]{"a","b"});
	}
	
}

    练习20:创建一个使用可变参数列表而不是普通的main()语法的main()。打印所产生的args数组的所有元素,并用各种不同数量的命令行参数来测试它。

package chapter5;

public class Session82 {

	public Session82(String ...a) {
		for (String string : a) {
			System.out.println(string);
		}
	}
	
	public static void main1(String...args) {
		Session82 session82 = new Session82("a","b");
		
		Session82 session821 = new Session82(new String[]{"a","b"});
	}
	
}

    5.9 枚举类型

    练习21:创建一个enum,它包含纸币中最小面值的6种类型。通过values()循环并打印每一个值及其ordinal();

package chapter5;

public enum Session9 {

	YIMAO,YIKUAI,SHIKUAI,YIBAIKUAI
	//一毛,一块,十块,一百块
}
package chapter5;

public class TestSession9 {

	public static void main(String[] args) {
		for (Session9 string : Session9.values()) {
			System.out.println(string);
			System.out.println(string.ordinal());
		}
        //YIMAO
        //0
        //YIKUAI
        //1
        //SHIKUAI
        //2
        //YIBAIKUAI
        //3
	}

}

        练习22:在前面的例子中,为enum写一个switch语句,对于每一个case,输出该特定货币的描述

package chapter5;

public class TestSession9 {

	public static void main(String[] args) {
		TestSession9 session9 = new TestSession9(Session9.SHIKUAI);
		session9.descript();
	}

	public TestSession9(Session9 session9) {
		this.session9 = session9;
	}

	private Session9 session9;

	void descript() {
		switch (session9) {
		case YIMAO:
			System.out.println("一毛");
			break;
		case YIKUAI:
			System.out.println("一块");
			break;
		case SHIKUAI:
			System.out.println("十块");
			break;
		case YIBAIKUAI:
			System.out.println("一百块");
			break;
		default:
			break;
		}
	}

}

 

© 著作权归作者所有

共有 人打赏支持
leooooo
粉丝 13
博文 19
码字总数 17933
作品 0
西安
高级程序员
C++不垃圾,只是Java很傲慢

《Thinking in C++》及《Thinking in Java》的作者Bruce Eckel向来是个“拥C++反Java”派,他曾经不止一次的提到,C++语言特性的添加有多么的深思熟虑,而Java又是如何的把一些奇怪的东西不停...

AlphaJay
2010/04/15
0
0
C++不垃圾,只是Java很傲慢

本文转自:http://developer.51cto.com/art/200906/131773.htm 《Thinking in C++》及《Thinking in Java》的作者Bruce Eckel向来是个“拥C++反Java”派,他曾经不止一次的提到,C++语言特性...

张明
2010/03/18
0
0
为什么我会弃Java,选择了Kotlin——专访《Java编程思想》作者 Bruce Eckel

点击上方“CSDN”,选择“置顶公众号” 关键时刻,第一时间送达! 这是前不久我们发布《Kotlin或将取代Java》一文之后,来自网友们的部分声音。 可以看到:作为编程语言界的老大——Java仍然...

csdnnews
05/30
0
0
Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区
05/09
0
0
Java finalize方法

《JAVA编程思想》: java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。 (1).对象不一定会被回收。 (2).垃圾回收不是析构函数。 (3).垃圾回收只与内存有关。 (4)....

清风伴月
2017/10/22
0
0
Java 使用 happen-before 规则实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道,JMM(Java 内存模型) 中的 happen-before(简称 hb)规则,该规则定义了 Java 多线程操作的有序性和可见性,防止了编译器重排序对程序结果的影响。按照官方的...

stateIs0
01/20
0
0
Java 8里面lambda的最佳实践

Java 8已经推出一段时间了,越来越多开发人员选择升级JDK,这条热门动弹里面看出,JDK7最多,其次是6和8,这是好事! 在8 里面Lambda是最火的主题,不仅仅是因为语法的改变,更重要的是带来了...

OSC闲人
2015/04/30
0
41
读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要)

读书笔记部分内容来源书出版书,版权归本书作者,如有错误,请指正。 欢迎star、fork,读书笔记系列会同步更新 git https://github.com/xuminwlt/j360-jdk module j360-jdk-thread/me.j360....

Hi徐敏
2015/11/11
0
1
注册中心 Eureka 源码解析 —— 应用实例注册发现(五)之过期

摘要: 原创出处 http://www.iocoder.cn/Eureka/instance-registry-evict/ 「芋道源码」欢迎转载,保留摘要,谢谢! 本文主要基于 Eureka 1.8.X 版本 1. 概述 2. 为什么需要过期 3. EvictionT...

芋道源码
05/25
0
0
学好Java只需要做到这7点,年薪20W很简单~

大道至简,所以扎实有用的方法,其实都是很简单的,难在踏踏实实的执行过程。今天为大家介绍的就是Java学习的7个看起来非常简单的方法,快学起来吧。 为什么要学习java? Java是目前最流行的...

欧阳海阳
06/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Git 2.18版本发布:支持Git协议v2,提升性能

Git 2.18版本发布:支持Git协议v2,提升性能Git 2.18版本发布:支持Git协议v2,提升性能 新版本协议的主要驱动力是使 Git 服务端能够对各种 ref(分支与 tag)进行过滤操作。 这就意味着,G...

linux-tao
30分钟前
0
0
python浏览器自动化测试库【2018/7/22-更新】

64位py2.7版本 更新 document_GetResources 枚举页面资源 document_GetresourceText 获取指定url的内容 包括页面图片 下载地址下载地址 密码:upr47x...

开飞色
46分钟前
28
0
关于DCL双重锁失效及解决方案

关于DCL双重锁失效及解决方案 Double Check Lock (DCL)实现单例 DCL 方式实现单例的优点是既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance方法不进行...

DannyCoder
52分钟前
0
0
PowerDesigner 16.5 安装配置

PowerDesigner16.5破解版是一款业内领先且开发人员常用的数据库建模工具,PowerDesigner可以从物理和概念两个层面设计数据库,方便用户制作处清晰直观的数据流程图和结构模型,欢迎有需要的朋...

Gibbons
今天
0
0
mac Homebrew 指令积累

1通用命令 brew install [包名] //安装包 brew list //列举安装的包 brew info [包名] // 显示安装包的详细信息 mysql 相关 #启动mysql 服务 brew service start mysql my...

Kenny100120
今天
0
0
前端Tips: 创建, 发布自己的 Vue UI 组件库

创建, 发布自己的 Vue UI 组件库 前言 在使用 Vue 进行日常开发时, 我们经常会用到一些开源的 UI 库, 如: Element-UI, Vuetify 等. 只需一行命令, 即可方便的将这些库引入我们当前的项目: n...

ssthouse_hust
今天
1
0
大数据教程(2.13):keepalived+nginx(多主多活)高可用集群搭建教程【自动化脚本】

上一章节博主为大家介绍了目前大型互联网项目的keepalived+nginx(主备)高可用系统架构体系,相信大家应该看了博主的文章对keepalived/nginx技术已经有一定的了解,在本节博主将为大家分享k...

em_aaron
今天
5
0
Git 2.18版本发布:支持Git协议v2,提升性能

在最新的官方 Git 客户端正式版2.18中添加了对 Git wire 协议 v2 的支持,并引入了一些性能与 UI 改进的新特性。在 Git 的核心团队成员 Brandon Williams 公开宣布这一消息前几周,Git 协议 ...

六库科技
今天
0
0
Java8新特性之接口

在JDK8以前,我们定义接口类中,方法都是抽象的,并且不能存在静态方法。所有的方法命名规则基本上都是 public [返回类型] [方法名](参数params) throws [异常类型] {}。 JDK8为接口的定义带...

developlee的潇洒人生
今天
0
0
aop + annotation 实现统一日志记录

aop + annotation 实现统一日志记录 在开发中,我们可能需要记录异常日志。由于异常比较分散,每个 service 方法都可能发生异常,如果我们都去做处理,会出现很多重复编码,也不好维护。这种...

长安一梦
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部