第二章 一切都是对象
Java是基于C++的,但是Java是一种更"纯粹"的面向对象程序设计语言。
Java和C++都是混合/杂合型语言。
2.1 用引用操纵对象
在Java中一切都被视为对象,但是操纵的标识符实际上是一个"引用"(reference)。
比如:String s;这里创建的知识引用,并不是对象。
String s = "abcd";字符串可以用带引号的文本初始化。
2.2 必须由你创建所有对象
new关键字 创建新的对象
String s = new String("abcd");这里面(String s)是一个引用,(new String("abcd"))是创建的新对象。
这个引用是指向创建的新的对象。
2.2.1 存储到什么地方
- 寄存器。这里是最快的存储区,位于处理器内部。寄存器根据需求分配,java不能直接控制,c和c++可以向编译器建议寄存器的分配。
- 堆栈。位于通用RAM(随机访问存储器),通过堆栈指针可以从处理器那里获得直接支持。堆栈向下移动,分配新的内存,向上移动释放那些内存。快速的分配存储方式,仅次于寄存器。Java系统必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针。Java对象引用存放在堆栈里,对象不在这里。
- 堆。一种通用的内存池(位于RAM区)。用于存放所有Java对象。堆不同于堆栈的好处:编译器不需要知道存储数据在堆里存活多长时间。因此堆分配存储有很大的灵活性。写一个new对象后,会自动在堆里进行存储分配。用堆进行存储分配和清理会比堆栈进行存储分配需要更多的时间。
- 常量存储。常量值通常直接存放在程序代码内部。常量存储不会改变。在嵌入式系统中,可以选择存放在ROM(只读存储器)。
- 非RAM存储。数据完全存活于程序之外,不受程序控制,在程序没有运行时也可以存在。例子:流对象和持久化对象。我的理解是例如数据库的连接,JDBC啥的。
2.2.2 特例:基本类型
基本类型不用new来创建,而是创建一个并非是引用的"自动"变量。这个变量直接存储"值",并置于堆栈中。
基本类型存储空间大小固定不变。
基本类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
boolean | - | - | - | Boolean |
char | 16bits | Unicod 0 | Unicode 2^16-1 | Character |
byte | 8bits | -128 | +127 | Byte |
short | 16bits | -2^15 | +2^15-1 | Short |
int | 32bits | -2^31 | +2^31-1 | Integer |
long | 64bits | -2^63 | +2^63-1 | Long |
float | 32bits | IEEE754 | IEEE754 | Float |
double | 64bits | IEEE754 | IEEE754 | Double |
void | - | - | - | Void |
所有数值类型都有正负号。
包装器类型。
2.2.3 Java中的数组
Java确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价。但是换来的是安全性。
创建一个数组对象,实际上是创建一个引用数组。每个引用都会自动初始化为一个特定值,这个值拥有自己的关键字null。一旦Java看到null,就知道引用还没指向某个对象。因此运行时就会报错。
2.3 永远不需要销毁对象
2.3.1 作用域
只要知道Java不能这样写:
{
int x = 12;
{
int x = 34;
}
}
Java不允许,虽然C和C++允许,小作用域起作用。因为这样不易阅读代码。
2.3.2 对象的作用域
Java对象和基本类型有着不一样的生命周期。当new一个对象时,对象可以存活于作用域之外。
例如:
{
String s = new String(“abcd”);
}
引用s在作用域终点消失。但是s指向的String对象仍然继续占据内存空间。后续会有在程序执行过程中,如何传递和复制对象引用。
但是如果Java让对象继续存在,那么如何防止填满内存空间的呢?
Java的垃圾回收器,用来监视用new创建的所有对象,并辨别不再被引用的对象,随后释放这些对象的内存空间。
2.4 创建新的数据类型:类
class 类
2.4.1 字段和方法
字段(成员变量)
方法(成员函数)
基本成员默认值:当基本数据类型作为类的成员使用时,Java才会给一个默认值。
基本类型 | 默认值 |
boolean | false |
char | '\u0000'(null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
但是如果是局部的就不会。例如:
int x;//x可以是任意值
2.5 方法、参数和返回值
2.5.1 参数列表
2.6 构建一个Java程序
2.6.1 名字可见性
2.6.2 运用其他构件
2.6.3 static关键字
static字段 static方法
2.7 你的第一个Java程序
java.lang是默认导入到每个Java文件中
类的名字必须和文件名相同。
System.getProperties().list(System.out);//获取程序中所有属性
2.7.1 编译和运行
2.8 注释和嵌入式文档
/*
* 多行注释
*/
//单行注释
2.8.1 注释文档
javadoc,输出的是一个HTML文件。
2.8.2 语法
javadoc命令都只能在“/**”注释中出现,记得是两个星号,注释结束于“*/”。
使用javadoc主要有来两种方式:嵌入HTML,或使用“文档标签”。独立文档标签是一些以“@”字符开头的命令,且要置于注释行的最前面(但是不算前导“*”之后的最前面)。而“行内文档标签”
则可以出现在java注释的任何地方看,它们也是以“@”字符开头,但是括号在花括号内。
//: object/Documentation1.java
/** A class comment */
public class Documentation1 {
/** A field comment */
public int i;
/** A method commnet */
public void f() {}
} ///:~
javadoc只能为public和protected成员进行文档注释,private和默认的包内可访问成员的注释会被忽略掉。但是private可以添加-private进行标记,以便private成员也可以被注释。
2.8.3 嵌入式HTML
这个有点厉害,就是可以在/** */里面添加一些HTML的语言比如
/**
* <ol>
* <li>
* <li>
* </ol>
*/
每一行开头的星号和前导空格都会被javadoc丢弃
2.8.4 一些标签示例
- @see:引用其他类
- {@link package.class#member label}
- {@docRoot}:文档根路径的相对路径
- {@inheritDoc}:当前类最直接的基类中继承相关文档到当前文件注释中
- @version:格式(@version version-information)后面跟着的是版本信息
- @author:格式(@author author-information)作者的信息,姓名啊邮箱啊都可以写在这里
- @since:所用JDK版本情况。
- @param:格式(@param parameter-name description)参数名称 参数描述(可以延续数行,知道新的文本标签出现为止)
- @return:格式(@return description)返回值的描述
- @throws:格式(@throws fully-qualified-class-name description)fully-qualified-class-name给出一个异常类的无歧义的名字
- @deprecated:旧特性已右新特性所取代,建议用户不要再使用这些旧特性,因为不久就会这些旧特性可能会被删除。使用这个标签会引起编译器警告
2.8.5 文档示例
2.9 编码风格
驼峰风格