首页 > 代码库 > 第二章 一切都是对象

第二章 一切都是对象

在本章,我们将看到 Java 程序的基本组成部分,并体会到在 Java 中几乎一切都是对象。

 

2.1 用引用操纵对象

Java 中通过引用(遥控器)操纵对象(电视机)。

引用可以单独存在,并不一定需要一个对象与之关联,比如 String s; 这里创建的只是引用,不是对象。如果此时向 s 发送一个消息(调用 s 的方法)就会报错。因为此时 s 实际上没有和任何事物关联。

所以,一种安全的做法是:创建引用的同时进行初始化,比如 String s = "asdf; (这里直接赋值一个字符串字面量,通常使用一种更通用的方式)。

 

 

2.2 必须由你创建所有对象

通常用 new 操作符创建新对象,所以前面的例子可以写成 String s = new String("asdf");

2.2.1 存储到什么地方?

  • 寄存器
    • 是最快的存储区,位于处理器内部。寄存器的数量极其有限,所以根据需求进行分配,你无法直接控制。
  • 堆栈
    • 位于通用RAM中。创建程序时,Java 系统必须知道存储在堆栈中所有项的确切生命周期,以便上下移动堆栈指针。这一约束限制了程序的灵活性。
    • 对象引用存储于堆栈中。
    • 存放所有的 Java 对象。
    • 相比于堆栈,优点是编译器不需要知道存储在堆中的数据存活多久,缺点是比使用堆栈效率低。
  • 常量存储
    • 常量值通常直接存放在程序代码内部。
  • 非RAM存储
    • 流对象和持久化对象。

2.2.2 特例:基本类型

因为 new 将对象存储在堆里,对于小的、简单的变量来说,往往不是很有效。因此,对于基本类型,Java 不用 new 创建变量,而是创建一个并非是引用的变量,该变量直接存储值,并置于堆栈中,更加高效。

Java 的基本类型所占存储空间的大小不随机器硬件架构的变化而变化。这也是 Java 编写的程序更具有可移植性的原因之一。

基本类型 位数 包装器类型
boolean   Boolean
char 16 Character
byte 8 Byte
short 16 Short
int 32 Int
long 64 Long
float 32 Float
double 64 Double

 

 

 

 

 

 

 

  

 

boolean类型所占存储空间的大小没有明确指定,只能取字面值 true 或 false。

JavaSE5 的自动包装功能实现基本类型和包装器类型之间的相互转换:

Character ch = ‘x‘;
char c = ch;

Java 提供了两个用于高精度计算的类:BigInteger 和 BigDecimal。这两个类提供的操作与对基本类型所能做的操作相似。只不过必须以方法调用的形式取代运算符形式。

2.2.3 Java中的数组

Java 确保数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销和运行时的下标检查为代价的。由此换来的是安全性和效率的提高。

创建一个数组对象时,实际就是创建一个引用数组,并且每个引用都会自动被初始化为一个特定值,该值拥有自己的关键字 null。一旦 Java 看到 null,就会知道这个引用还没有指向某个对象。

在使用任何引用之前,必须为其指定一个对象;如果试图使用为 null 的引用,运行时将会报错。

 

 

2.3 永远不需要销毁对象

2.3.1 作用域

大多数过程型语言都有“作用域”的概念。作用域决定了在其内定义的变量名的可见性和生命周期。

在 Java 中,作用域由花括号的位置决定。在作用域中定义的变量只可用于作用域结束之前。

Java 中不允许如下书写:

{
    int x = 12;
    {
        int x = 96;
    }
}        

编译器将会报告变量 x 已经定义过。

2.3.2 对象的作用域

用 new 创建的对象可以存活于作用域之外。

{
    String s = new String("asdf");    
}

引用 s 在作用域结束就消失了。而 s 指向的对象仍然存活在堆中。在这段代码中,我们无法在这个作用域之后访问这个对象,因为对它的唯一引用已经超出了作用域的范围。

如何防止内存空间被填满?Java 有一个垃圾回收器,用来监视用 new 创建的所有对象,并识别出那些不会再被引用的对象。随后,释放这些对象的内存空间,以供新的对象使用。

 

 

2.4 创建新的数据类型:类

定义新类的方式:  class ATypeName { /* class body*/ }

创建该类型的对象:   ATypeName a = new ATypeName();

一旦定义一个类(Java 中你所要做的就是定义类,产生这些类的对象,向这些对象发送消息),就可以在类中设置类的字段和方法。字段可以是基本类型,也可以是引用类型。

如何引用一个对象的成员:obj.member  obj.subobj.member

若类的某个成员是基本数据类型,即使没有进行初始化,Java 也会确保它获得一个默认值:

基本类型 默认值
boolean false
char ‘\u0000‘
byte 0
short 0
int 0
long 0
float 0.0f
double 0.0d

 

 

 

 

 

 

 

 

 

2.5 方法、参数和返回值

Java 的方法决定了一个对象能够接收什么样的消息。方法的基本组成包括:名称、参数、返回值和方法体。下面是其基本格式:

返回值类型 方法名( 参数列表 ){
    方法体;
}

返回类型描述的是调用方法之后从方法返回的值。参数列表给出了要传给方法的信息的类型和名称。方法名和参数列表(合称为“方法签名”)唯一的标识一个方法。

Java 中的方法只能定义在类的里面。

通过对象调用方法:obj.methodName( arg1,arg2,arg3 );

return 的作用:① 结束此方法;② 返回方法的结果。

 

 

2.6 构建一个 Java 程序

2.6.1 名字可见性

反转域名,包名都是小写,比如:com.leoxk.demo.javase

2.6.2 运用其他构件

导入一个类:import java.util.ArrayList;

批量导入类:import java.util.*;

2.6.3 static关键字

当声明一个成员是 static 时,意味着这个字段或方法不会与包含它的那个类的任何对象实例联系在一起。即使没有创建该类的对象,也可以调用其 static 字段或方法。

可以通过类名访问,也可以通过变量访问,推荐使用类名访问。

 

 

2.7 你的第一个 Java 程序

未完待续~~~~~~~~~~

 

第二章 一切都是对象