第二章 一起都是对象
目录
2.1 用引用操作对象
引用(reference)
引用并不一定需要有一个对象与它关联
创建一个引用的同时初始化(运行时错)
2.2 必须由你创建所有对象
new操作符
2.2.1 存储到什么地方
存储数据的地方:
1)寄存器
最快、数量有限、不能直接控制
2)堆栈
位于通用RAM(随机访问存储器)
通过堆栈指针可以从处理器那里获得直接支持
指针下移:分配新的内存
指针上移:释放内存
迅速有效(仅次于寄存器)
创建程序时,JAVA系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动指针(限制了程序的灵活性)
虽然某些JAVA数据存储于堆栈中——特别是对象引用,但JAVA对象并不存储于其中
3)堆
一种通用的内存池(也位于RAM中)
用于存放所有JAVA对象
好处:编译器不需要知道存储的数据在堆里存活多长时间(灵活性)
代价:用堆进行存储分配和清理可能比用堆栈进行存储分配需要更多的时间
4)常量存储
常量值通常直接存放在程序代码内部
安全:永远不会改
有时在嵌入式系统中,存放在ROM(只读存储器)
5)非RAM存储
数据完全存活于程序之外,不受程序的任何控制
e.g. 流对象(对象转化成字节流,通常被发送到另一台机器)
持久化对象(对象呗存放在磁盘上,即使程序终止,它们仍可保持自己的状态)
JAVA提供了对轻量级持久化的支持(如:JDBC Hibernate)
2.2.2 特例:基本类型
基本类型 | 大小 | 包装器类型 |
---|---|---|
boolean | - | Boolean |
char | 16 bits | Character |
byte | 8 bits | Byte |
short | 16 bits | Short |
int | 32 bits | Integer |
long | 64 bits | Long |
float | 32 bits | Float |
double | 64 bits | Double |
void | - | Void |
所有数值类型都有正负号
boolean类型所占存储空间的大小没有明确指定,仅定义为能够取字面值true false
基本类型具有的包装器类使得可以在堆中创建一个非基本对象,用来表示对应的基本类型
Java SE5:自动包装功能
高精度数字
BigInteger:任意精度的整数
BigDecimal:任意精度的定点数
大体上属于“包装器类”的范畴,但没有对应的基本类型
包含的方法,提供的操作和对基本类型所能执行的操作相似(int float),必须以方法调用方式取代运算符方式(运算速度慢)
2.2.3 Java中的数组
Java确保数组会被初始化,且不能在范围外被访问
范围检查:以每个数组上少量的内存开销及运行时的下标检查为代价
安全性和效率的提高
当创建一个数组对象时,实际上就是创建了一个引用数组,并且每个引用都会自动被初始化为一个特定值null
在使用任何引用前,必须为其指定一个对象(否则在运行时将会报错)
当创建用来存放基本数据类型的数组:编译器确保这种数组的初始化,将所占的内存全部置零
2.3 永远不需要销毁对象
2.3.1 作用域(scope)
作用域决定了在其内定义的变量名的可见性和生命周期
作用域有花括号的位置决定
作用域内定义的变量只可用于作用域结束之前
2.3.2 对象的作用域
Java对象不具备和基本类型一样的生命周期。当new一个Java对象时,它可以存活于作用域之外。
如:
{
String s = new String("a string");
}// End of scope
引用s在作用域终点小时,而s指向的String对象仍占据内存空间
由new创建的对象,只要你需要,就会一直保留下去
垃圾回收器:用来监视用new创建的对象,并辨别哪些不会在被引用的对象,随后释放这些对象的内存空间,以便其他新的对象使用。
2.4 创建新的数据类型:类
2.4.1 字段和方法
可以在类中定义两种类型的元素:
字段(数据成员):可以是任何类型的对象(初始化),可以通过其引用与其进行通信;也可以是基本数据类型
方法(成员函数)
DataOnly类
基本成员默认值
基本类型 | 默认值 |
---|---|
boolean | false |
char | '\u0000'(null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
当变量作为类的成员使用时,Java才确保给定其默认值(不适用于局部变量)
2.5 方法、参数和返回值
方法、函数
Java的方法决定了一个对象能够接收什么样的消息
方法的基本组成部分:
名称
参数
参数列表给出了要传给方法的信息的类型和名称
返回值
返回类型描述的是在调用方法之后从方法返回的值
方法体
方法名和参数列表(合称为“方法签名”)唯一地标识出某个方法
Java中的方法只能作为类的一部分来创建
方法只有通过对象才能调用(static方法针对类调用,不依赖于对象的存在)
调用方法:发消息给对象
2.5.1 参数列表
方法的参数列表指定要传递给方法什么样的信息(对象形式,实际上是引用)
return关键字:1.已经做完,离开此方法
2.返回值
2.6 构建一个Java程序
2.6.1 名字可见性
为了给一个类库生成不会与其他名字混淆的名字,Java设计者希望程序员使用自己的域名(保证独一无二)
所有的文件都能够自动存活于他们自己的名字空间内,而且同一个文件内的每个类都有唯一的标识符
2.6.2 运用其他构件
import:指示编译器导入一个包(类库)
2.6.3 static关键字
需要:1. 只想为某特定域分配单一存储空间,而不去考虑究竟需要创建多少对象,甚至根本就不创建任何对象
2. 希望某个方法不与包含它的类的任何对象关联在一起(即使没有创建对象,也能够调用方法)
当static作用于某个字段是,会改变数据创建的方式
一个static字段对每个类来说都只有一份存储空间
static方法常常拿来做“牧羊人”的角色,负责看护与其隶属同一类的实例群
2.7 你的第一个Java程序
// HelloDate.java
import java.util.*;
public class HelloDate{
public static void main(String[] args) {
System.out.println("Hello, it's: ");
System.out.println(new Date());
}
}
import语句:引入需要的额外的类(java.lang会自动被导入到每一个Java文件中)
system.out:一个静态PrintStream对象
//: object/ShowProperties.java
public class ShowProperties{
public static void main(String[] args){
System.getProperties().list(System.out);
System.out.println(System.getProperty("user.name"));
System.out.println(
System.getProperty("java.library.path")
);
}
} ///:~
第一行:显示从运行程序的系统中获得的所有“属性”,提供环境信息
list():将结果发给他的参数:System.out
2.7.1 编译和运行
javac java
2.8 注释和嵌入式文档
/* ... */
//...
2.8.1 注释文档
Javadoc:
用于提取注释的工具
采用了Java编译器的某些技术,查找程序内的特殊注释标签
不仅解析由这些标签标记的信息,还将毗邻注释的类名或方法名抽取出来
输出一个html文件
2.8.2 语法
Javadoc命令只能在/**注释中出现,注释结束于*/
使用方式:嵌入HTML或使用“文档标签”
独立文档标签:一些以@开头的命令,位于注释行不算前导*的最前面
行内文档标签:可以出现在Javadoc注视中的任何地方,以@开头,括在花括号内
三种类型的注释文档:类、域、方法
//: object/Documentation1.java
/** A class comment */
public class Documentation1{
/** A field comment */
public int i;
/** A method comment */
public void f() {}
} ///:~
注:Javadoc只能为public和protected成员进行文档注释;private和包内可访问成员的注释会被忽略
可以用-private进行标记,以便把private成员的注释也包括在内
2.8.3 嵌入式HTML
javadoc通过生成的HTML文档传输HTML命令
主要目的:对代码进行格式化
不要在嵌入式HTML中使用标题标签(如:<h1> <hr>)
所有类型的注释文档——类、域、方法,都支持嵌入式HTML
2.8.4 一些标签示例
@see:引用其他类,生成超链接“See Also”
{@link package.class#member label}:与@see类似,用于行内,用“label”作为超链接文本
{@docRoot}:产生到文件根目录的相对路径,用于文档树页面的显式超链接
{@inheritDoc}:从当前这个类的最直接的基类中继承相关文档
@version:格式:@version version-information
如果javadoc命令行使用了-version标记,从生成的HTML文档中特别提取出版本信息
@author:格式:@author author-information
如果javadoc命令行使用了-author标记,从生成的HTML文档中特别提取出作者信息
@since:允许指定程序代码最早使用的版本
@param:形式:@param parameter-name description
parameter-name是方法的参数列表中的标识符
description是可延续数行的文本,终止于新的文档标签出现之前
@return:形式:@return description
description描述返回值的含义,可延续数行
@throws:异常标签
格式:@throws fully-qualified-class-name description
fully-qualified-class-name:给出一个异常类的无歧义的名字
description:可延续数行
@deprecated:指定一些旧特性已由改进的新特性取代,建议用户不要再使用这些旧特性,因为在不久的将来它们可能会被删除
如果使用一个标记为@deprecated的方法,会引起编译器发布警告
在Java SE5中,javadoc标签@deprecated已经被@Deprecated注解所取代
2.9 代码风格
类名:首字母大写;如果类名由多个单词组成,把它们并在一起,每个单词的首字母大写
标识符:首字母小写
驼峰风格