《Java从小白到大牛》之第11章 对象

《Java从小白到大牛》纸质版已经上架了!!!

类实例化可生成对象,实例方法就是对象方法,实例变量就是对象属性。一个对象的生命周期包括三个阶段:创建、使用和销毁。前面章节已经多少用到了对象,这一章详细介绍一下对象的创建和销毁等相关知识。

创建对象

创建对象包括两个步骤:声明和实例化。

1. 声明

声明对象与声明普通变量没有区别,语法格式如下:

type objectName;

其中type是引用类型,即类、接口和数组。示例代码如下:

String name;

该语句声明了字符串类型对象name。可以声明并不为对象分配内存空间,而只是分配一个引用。

2. 实例化

实例化过程分为两个阶段:为对象分配内存空间和初始化对象,首先使用new运算符为对象分配内存空间,然后再调用构造方法初始化对象。示例代码如下:

String name;

name = new String("Hello World");

代码中String("Hello World")表达式就是调用String的构造方法。初始化完成之后如图11-1所示。

空对象

一个引用变量没有通过new分配内存空间,这个对象就是空对象,Java使用关键字null表示空对象。示例代码如下:

String name = null;

name = "Hello World";

引用变量默认值是null。当试图调用一个空对象的实例变量或实例方法时,会抛出空指针异常NullPointerException,如下代码所示:

String name = null;

//输出null字符串

System.out.println(name);

//调用length()方法

int len = name.length(); ①

但是代码运行到第①行时,系统会抛出异常。这是因为调用length()方法时,name是空对象。程序员应该避免调用空对象的成员变量和方法,代码如下:

//判断对象是否为null

if (name != null) {

int len = name.length();

}

提示 产生空对象有两种可能性:第一是程序员自己忘记了实例化,第二是空对象是别人传递给我们的。第一种程序员必须防止这种情况发生,应该仔细检查自己的代码,为自己创建的所有对象进行实例化并初始化。第二种情况需要通过判断对象非null进行避免。

构造方法

在11.1节使用了表达式new String("Hello World"),其中String("Hello World")是调用构造方法。构造方法是类中特殊方法,用来初始化类的实例变量,这个就是构造方法,它在创建对象(new运算符)之后自动调用。

Java构造方法的特点:

  1. 构造方法名必须与类名相同。
  2. 构造方法没有任何返回值,包括void。
  3. 构造方法只能与new运算符结合使用。

构造方法示例代码如下:

//Rectangle.java文件

package com.a51work6;

// 矩形类

public class Rectangle {

// 矩形宽度

int width;

// 矩形高度

int height;

// 矩形面积

int area;

// 构造方法

public Rectangle(int w, int h) { ①

width = w;

height = h;

area = getArea(w, h);

}

...

}

代码第①行是声明了一个构造方法,其中有两个参数w和h,用来初始化Rectangle对象的两个成员变量width和height,注意前面没有任何的返回值。

默认构造方法 {#-0}

有时在类中根本看不到任何的构造方法。例如本节中User类代码如下:

//User.java文件

package com.a51work6;

public class User {

// 用户名

private String username;

// 用户密码

private String password;

}

从上述User类代码,只有两个成员变量,看不到任何的构造方法,但是还是可以调用无参数的构造方法创建User对象,见如下代码。

//HelloWorld.java文件

...

User user = new User();

Java虚拟机为没有构造方法的类,提供一个无参数的默认构造方法,默认构造方法其方法体内无任何语句,默认构造方法相当于如下代码:

//默认构造方法

public User() {

}

默认构造方法的方法体内无任何语句,也就不能够初始化成员变量了,那么这些成员变量就会使用默认值,成员变量默认值是与数据类型有关,具体内容可以参考9.1.2节中的表9-1所示。这里不再赘述。

构造方法重载 {#-1}

在一个类中可以有多个构造方法,它们具体有相同的名字(与类名相同),参数列表不同,所以它们之间一定是重载关系。

构造方法重载示例代码如下:

//Person.java文件

package com.a51work6;

import java.util.Date;

public class Person {

// 名字

private String name;

// 年龄

private int age;

// 出生日期

private Date birthDate;

public Person(String n, int a, Date d) { ①

name = n;

age = a;

birthDate = d;

}

public Person(String n, int a) { ②

name = n;

age = a;

}

public Person(String n, Date d) { ③

name = n;

age = 30;

birthDate = d;

}

public Person(String n) { ④

name = n;

age = 30;

}

public String getInfo() {

StringBuilder sb = new StringBuilder();

sb.append("名字: ").append(name).append('\n');

sb.append("年龄: ").append(age).append('\n');

sb.append("出生日期: ").append(birthDate).append('\n');

return sb.toString();

}

}

上述代码Person类代码提供了4个重载的构造方法,如果有准确的姓名、年龄和出生日期信息,则可以选用代码第①行的构造方法创建Person对象;如果只有姓名和年龄信息则可选用代码第②行的构造方法创建Person对象;如果只有姓名和出生日期信息则可选用代码第③行的构造方法创建Person对象;如果只有姓名信息则可选用代码第④行的构造方法创建Person对象。

构造方法封装 {#-2}

构造方法也可以进行封装,访问级别与普通方法一样,构造方法的访问级别参考表11-1所示。示例代码如下:

//Person.java文件

package com.a51work6;

import java.util.Date;

public class Person {

// 名字

private String name;

// 年龄

private int age;

// 出生日期

private Date birthDate;

// 公有级别限制

public Person(String n, int a, Date d) { ①

name = n;

age = a;

birthDate = d;

}

// 默认级别限制

Person(String n, int a) { ②

name = n;

age = a;

}

// 保护级别限制

protected Person(String n, Date d) { ③

name = n;

age = 30;

birthDate = d;

}

// 私有级别限制

private Person(String n) { ④

name = n;

age = 30;

}

...

}

上述代码第①行是声明公有级别的构造方法。代码第②行是声明默认级别,默认级别只能在同一个包中访问。代码第③行是保护级别的构造方法,该构造方法在同一包中与默认级别相同,在不同包中可以被子类继承。代码第④行是私有级别构造方法,该构造方法只能在当前类中使用,不允许在外边访问,私有构造方法可以应用于单例设计模式^10等设计。

this关键字 {#this}

前面章节中使用过this关键字,this指向对象本身,一个类可以通过this来获得一个代表它自身的对象变量。this使用在如下三种情况中:

  • 调用实例变量。
  • 调用实例方法。
  • 调用其他构造方法。

使用this变量的示例代码:

//Person.java文件

package com.a51work6;

import java.util.Date;

public class Person {

// 名字

private String name;

// 年龄

private int age;

// 出生日期

private Date birthDate;

// 三个参数构造方法

public Person(String name, int age, Date d) { ①

this.name = name; ②

this.age = age; ③

birthDate = d;

System.out.println(this.toString()); ④

}

public Person(String name, int age) {

// 调用三个参数构造方法

this(name, age, null); ⑤

}

public Person(String name, Date d) {

// 调用三个参数构造方法

this(name, 30, d); ⑥

}

public Person(String name) {

// System.out.println(this.toString());

// 调用Person(String name, Date d)构造方法

this(name, null); ⑦

}

@Override

public String toString() {

return "Person [name=" + name ⑧

+ ", age=" + age ⑨

+ ", birthDate=" + birthDate + "]";

}

}

上述代码中多次用到了this关键字,下面详细分析一下。代码第①行声明三个参数构造方法,其中参数name和age与实例变量name和age命名冲突,参数是作用域为整个方法的局部变量,为了防止局部变量与成员变量命名发生冲突,可以使用this调用局部变量,见代码第②行和第③行。注意代码第⑧行和第⑨行的name和age变量没有冲突,所以可以不使用this调用。

this也可以调用本对象的方法,见代码第④行的this.toString()语句,这本例中this可以省略。

在多个构造方法重载时,一个构造方法可以调用其他的构造方法,这样可以减少代码量,上述代码第⑤行this(name, age, null)使用this调用其他构造方法。类似调用还有代码第⑥行的this(name, 30, d)和第⑦行的this(name, null)。

注意 使用this调用其他构造方法时,this语句一定是该构造方法的第一条语句。例如在代码第⑦行之前调用toString()方法则会发生错误。

对象销毁

对象不再使用时应该销毁。C++语言对象是通过delete语句手动释放,Java语言对象是由垃圾回收器(Garbage Collection)收集然后释放,程序员不用关系释放的细节。自动内存管理是现代计算机语言发展趋势,例如:C#语言的垃圾回收,Objective-C和Swift语言的ARC(内存自动引用计数管理)。

垃圾回收器(Garbage Collection)的工作原理是:当一个对象的引用不存在时,认为该对象不再需要,垃圾回收器自动扫描对象的动态内存区,把没有引用的对象作为垃圾收集起来并释放。

本章小结

通过对本章的学习,可以了解如何创建Java对象,理解构造方法的作用。此外,还介绍了this关键的使用。

配套视频

http://edu.51cto.com/topic/1246.html

配套源代码

http://www.zhijieketang.com/group/5

原文地址:http://blog.51cto.com/tonyguan/2162334

时间: 2024-08-30 10:13:44

《Java从小白到大牛》之第11章 对象的相关文章

《Java从小白到大牛精简版》——第1章 开篇综述

Java诞生到现在已经有20多年了,但是Java仍然是非常热门的编程语言之一,很多平台中使用Java开发.表1-1所示的是TIOBE社区发布的2016年5月和2017年5月的编程语言排行榜,可见Java语言的热度,或许这也是很多人选择学习Java的主要原因. 表 1-1 TIOBE编程语言排行榜 2017年5月 2016年5月 变化 编程语言 评级 评级变化 1 1 Java 14.639% -6.320% 2 2 C 7.002% -6.220% 3 3 C++ 4.751% -1.950%

《Java从小白到大牛》之第12章 继承与多态

<Java从小白到大牛>纸质版已经上架了!!! 类的继承性是面向对象语言的基本特性,多态性前提是继承性.Java支持继承性和多态性.这一章讨论Java继承性和多态性. Java中的继承 {#java} 为了了解继承性,先看这样一个场景:一位面向对象的程序员小赵,在编程过程中需要描述和处理个人信息,于是定义了类Person,如下所示: //Person.java文件 package com.a51work6; import java.util.Date; public class Person

《Java从小白到大牛精简版》——前言

内容简介 本书是一本Java语言学习教程,读者群是零基础小白,通过本书的学习能够成为Java大牛.主要内容包括:Java语法基础.数据类型.运算符.控制语句.数组.字符串.面向对象基础.继承与多态.抽象类与接口.集合框架.异常处理.输入输出和网络编程等技术. 版权声明 <Java从小白到大牛精简版>免费电子图书是作者关东升原创作品,作者已将该书(包括:文字.图片和源代码)进行了版权注册,版权归作者关东升所有,仅供个人研究和学习之用.任何单位或个人不得以任何方式进行出版.篡改.编辑,任何单位或个

《Java从小白到大牛》之第7章 控制语句

<Java从小白到大牛>纸质版已经上架了!!! 程序设计中的控制语句有三种,即顺序.分支和循环语句.Java程序通过控制语句来管理程序流,完成一定的任务.程序流是由若干个语句组成的,语句可以是一条单一的语句,也可以是一个用大括号({})括起来的复合语句.Java中的控制语句有以下几类: 分支语句:if和switch. 循环语句:while.do-while和for 跳转语句:break.continue.return和throw 7.1 分支语句 分支语句提供了一种控制机制,使得程序具有了&q

《Java从小白到大牛》之第10章 面向对象基础(下)

<Java从小白到大牛>纸质版已经上架了!!! 封装性与访问控制 Java面向对象的封装性是通过对成员变量和方法进行访问控制实现的,访问控制分为4个等级:私有.默认.保护和公有,具体规则如表10-1所示. 表 101 Java类成员的访问控制 可否直接访问控制等级 同一个类 同一个包 不同包的子类 不同包非子类 私有 Yes 默认 Yes Yes 保护 Yes Yes Yes 公有 Yes Yes Yes Yes 下面详细解释一下这4种访问级别. 私有级别 {#-0} 私有级别的关键字是pri

《Java从小白到大牛》之第14章 异常处理(下)

<Java从小白到大牛>纸质版已经上架了!!! 释放资源 有时在try-catch语句中会占用一些非Java资源,如:打开文件.网络连接.打开数据库连接和使用数据结果集等,这些资源并非Java资源,不能通过JVM的垃圾收集器回收,需要程序员释放.为了确保这些资源能够被释放可以使用finally代码块或Java 7之后提供自动资源管理(Automatic Resource Management)技术. finally代码块 {#finally} try-catch语句后面还可以跟有一个final

《Python从小白到大牛》第1章 开篇综述

Python诞生到现在已经有20多年了,但是Python仍然是非常热门的编程语言之一,很多平台中使用Python开发.表1-1所示的是TIOBE社区发布的2017年3月和2018年3月的编程语言排行榜,可见Python语言的热度,或许这也是很多人选择学习Python的主要原因. Python语言历史 Python之父荷兰人吉多 范·罗苏姆(Guido vanRossum)在1989年圣诞节期间,在阿姆斯特丹,为了打发圣诞节的无聊时间,决心开发一门解释程序语言.1991年第一个Python解释器公

《Python从小白到大牛》第5章 Python编码规范

俗话说:"没有规矩不成方圆".编程工作往往都是一个团队协同进行,因而一致的编码规范非常有必要,这样写成的代码便于团队中的其他人员阅读,也便于编写者自己以后阅读. 提示关于本书的Python编码规范借鉴了Python官方的PEP8编码规范^1和谷歌Python编码规范^2. 命名规范 程序代码中到处都是标识符,因此取一个一致并且符合规范的名字非常重要.Python中命名规范采用多种不同.不同的代码元素命名不同,下面分类说明一下. 包名.全部小写字母,中间可以由点分隔开,不推荐使用下划线.

《Python从小白到大牛》第8章 控制语句

程序设计中的控制语句有三种,即顺序.分支和循环语句.Python程序通过控制语句来管理程序流,完成一定的任务.程序流是由若干个语句组成的,语句可以是一条单一的语句,也可以是复合语句.Python中的控制语句有以下几类: 分支语句:if 循环语句:while和for 跳转语句:break.continue和return 分支语句 分支语句提供了一种控制机制,使得程序具有了"判断能力",能够像人类的大脑一样分析问题.分支语句又称条件语句,条件语句使部分程序可根据某些表达式的值被有选择地执行