本章要点
- 对象操纵
- 对象创建
- 代码注释
- 对象清理
- 类的创建
C++是C的超集,允许多种编程风格,Java是更纯粹的面向对象编程语言,本章了解Java程序的基本组成,学习Java中万物皆对象的思想。
一、对象操纵
C/C++中,对象的操纵是通过指针完成的,而Java操纵的标识符实际上是对象的“引用”。
String s;
这个语句只是创建了一个String对象的引用,而非对象。
二、对象的创建
Java通常使用new操作符来创建对象,“引用”用来关联“对象”。
String s = new String("Hello world")
1、数据的存储
寄存器(Registers)最快的存储区域,位于 CPU 内部 。然而,寄存器的数量十分有限,所以寄存器根据需求进行分配。我们对其没有直接的控制权,也无法在自己的程序里找到寄存器存在的踪迹(另一方面,C/C++ 允许开发者向编译器建议寄存器的分配)。
栈内存(Stack)存在于常规内存 RAM(随机访问存储器,Random Access Memory)区域中,可通过栈指针获得处理器的直接支持。栈指针下移分配内存,上移释放内存,这是一种快速有效的内存分配方法,速度仅次于寄存器。创建程序时,Java 系统必须准确地知道栈内保存的所有项的生命周期。这种约束限制了程序的灵活性。因此,虽然在栈内存上存在一些 Java 数据,特别是对象引用,但 Java 对象却是保存在堆内存的。
堆内存(Heap)这是一种通用的内存池(也在 RAM 区域),所有 Java 对象都存在于其中。与栈内存不同,编译器不需要知道对象必须在堆内存上停留多长时间。因此,用堆内存保存数据更具灵活性。创建一个对象时,只需用 new 命令实例化对象即可,当执行代码时,会自动在堆中进行内存分配。这种灵活性是有代价的:分配和清理堆内存要比栈内存需要更多的时间(如果可以用 Java 在栈内存上创建对象,就像在 C++ 中那样的话)。随着时间的推移,Java 的堆内存分配机制现在已经非常快,因此这不是一个值得关心的问题了。
常量存储(Constant storage)常量值通常直接放在程序代码中,因为它们永远不会改变。如需严格保护,可考虑将它们置于只读存储器 ROM (只读存储器,Read Only Memory)中 。
非 RAM 存储(NonRAM storage)数据完全存在于程序之外,在程序未运行以及脱离程序控制后依然存在。两个主要的例子:(1)序列化对象:对象被转换为字节流,通常被发送到另一台机器;(2)持久化对象:对象被放置在磁盘上,即使程序终止,数据依然存在。这些存储的方式都是将对象转存于另一个介质中,并在需要时恢复成常规的、基于 RAM 的对象。Java 为轻量级持久化提供了支持。而诸如 JDBC 和 Hibernate 这些类库为使用数据库存储和检索对象信息提供了更复杂的支持。
1.1、基本类型的存储
通常new创建的对象保存在堆内存(小而简单的变量不划算),基本类型使用一个“自动”变量直接存储“值”并置于栈内存。
Java确定了每种基本类型的内存占用大小,不随机器环境变化,更具可移植性。基本类型有对应的包装类型,在堆内存里表示基本类型的数据需要用到包装类。
基本类型 | 大小 | 最小值 | 最大值 | 包装类型 |
---|---|---|---|---|
boolean | — | — | — | Boolean |
char | 16 bits | Unicode 0 | Unicode 216 -1 | Character |
byte | 8 bits | -128 | +127 | Byte |
short | 16 bits | - 215 | + 215 -1 | Short |
int | 32 bits | - 231 | + 231 -1 | Integer |
long | 64 bits | - 263 | + 263 -1 | Long |
float | 32 bits | IEEE754 | IEEE754 | Float |
double | 64 bits | IEEE754 | IEEE754 | Double |
void | — | — | — | Void |
char c='x'; //位于栈内存
Character ch=new Character(c); //转换为包装类型,位于堆内存中
1.2、高精度数值
Java提供两种类型的数据用于高精度计算——BigInteger和BigDecimal。
与int和float的操作相似,但必须通过调用它们的方法来实现而非运算符,在运算过程中不会丢失精度。
1.3、数组的存储
C和C++中数组是内存块,程序访问内存块之外的数组或在初始化之前使用该段内存,结果不可预测。
Java中数组使用前需要被初始化,并且不能访问数组长度以外的数据。创建对象数组时,实际创建了一个引用数组,引用的初始值为null,在使用前必须为每个引用指定一个对象。
三、代码注释
/*这是
*跨越多行的
*注释
*传统的C风格注释
*/
//这是单行注释,来自C++
四、对象清理
管理变量的生命周期需要大量工作。
1、作用域
作用域决定了在该范围内定义的变量名的可见性和生存周期。在 C、C++ 和 Java 中,作用域是由大括号 {} 的位置决定的。
{
int x=12;
//仅x可用
{
int y=96;
//x,y都可用
}
//仅x可用
}
Java中,额外的空格、制表符和回车并不会影响程序的执行结果。Java不会像C和C++把较大作用域的变量“隐藏”起来,以下代码是不合法的。
{
int x=1;
{
int x=2;
}
}
2、对象作用域
当我们使用 new 关键字来创建 Java 对象时,它的生命周期将会超出作用域。
{
String s=new String("Hello world");
}
//作用域终点
引用s的作用域在终点结束,但是s指向的对象依然占用内存。此例中对象唯一引用超出作用域范围,对象将不再可达,Java 的垃圾收集器会检查所有 new 出来的对象并判断哪些不再可达,继而释放那些被占用的内存,供其他新的对象使用。
五、类的创建
通过class关键字创建类,在class关键字后面紧跟类的名称,我们可以往类里存放两种类型的元素:方法(method)和字段(field)。类的字段可以是基本类型,也可以是引用类型。如果类的字段是对某个对象的引用,那么必须要初始化该引用将其关联到一个实际的对象上。
class Person{
int age;
double height;
boolean alive;
}//创建类及其字段
Person p=new Person();//创建类的对象
p.age=18;//修改对象p的数据;
1、基本类型默认值
如果类的成员变量(字段)是基本类型,那么在类初始化时,这些类型将会被赋予一个初始值。这种默认值的赋予并不适用于局部变量,为了安全,我们最好始终显式地初始化变量。
基本类型 | 初始值 |
---|---|
boolean | false |
char | \u0000 (null) |
byte | (byte) 0 |
short | (short) 0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
2、方法使用
在 Java 中,方法决定对象能接收哪些消息。方法的基本组成部分包括名称、参数、返回类型、方法体。方法的返回类型表明了当你调用它时会返回的结果类型。参数列表则显示了可被传递到方法内部的参数类型及名称。方法名和参数列表统称为方法签名(signature of the method)。签名作为方法的唯一标识。Java 中的方法只能作为类的一部分创建。它只能被对象所调用 ,并且该对象必须有权限来执行调用。
[返回类型][方法名](参数列表){
//方法体
//返回类型必须与变量类型兼容
//参数列表必须指定每个对象的类型和名称
//return执行两个操作,一是方法的结束,二是返回值
}
class Person{//创建类
int age=18;
int personAge(Person p){//在类里创建方法
return p.age;//返回int类型的age值
}
}
六、程序编写
命名可见性
为防止两个名称发生“冲突”,C++ 使用附加 的关键字引入了命名空间。Java 创建者希望我们反向使用自己的网络域名,因为域名通常是唯一的。此机制意味着所有文件都自动存在于自己的命名空间中,文件中的每个类都具有唯一标识符。
使用其它组件
import 指示编译器导入一个包,也就是一个类库。
import java.util.*;
static关键字
类是对象的外观及行为方式的描述。通常只有在使用 new 创建那个类的对象后,数据存储空间才被分配,对象的方法才能供外界调用。当我们说某个事物是静态时,就意味着该字段或方法不依赖于任何特定的对象实例。可以通过类名直接引用,使用类名直接引用静态变量是首选方法。static 关键字的这些特性对于应用程序入口点的 main() 方法尤为重要。
class StaticTest{
static int i=19;
}
StaticTest st=new StaticTest();
int out=st.i;//使用对象访问
int out1=StaticTest.i;//使用类名直接访问,首选方法
编码风格
Java 编程语言编码规范要求类 名的首字母大写。如果类名是由多个单词构成的,则每个单词的首字母都应大写(不采用下划线来分隔)。有时称这种命名风格叫“驼峰命名法”。对于几乎所有其他方法,字段(成员变量)和对象引用名都 采用驼峰命名的方式,但是它们的首字母不需要大写。
七、本章小结
本章展示了简单的 Java 程序编写以及该语言相关的基本概念。