《JAVA编程思想第四版》——一切都是对象
2.1 用句柄操纵对象
JAVA中一切都可“看做”对象。操作对象的方式是通过一个指向对象的句柄(又称引用或指针)。但是句柄并不一定指向对象,此时操作句柄会获得一个错误(运行期)
比如:String s;s.length();
这里创建句柄s,s并没有指向对象。如果此时向s发送一条消息会报错。编译器提示“the local variable s may not have been initialized”
String s = new String("hello,world!");s.length();
这里创建句柄s,s指向一个对象(对象位于堆区),向s发送消息正常。
2.2 所有对象都必须创建
创建句柄时,一般也同时将其指向某个对象。对象的创建方式为 new 关键字。
String s = new String("hello,world!");
2.2.1 数据保存的位置
①寄存器,位于处理器内部。根据需要由编译器分配。
②堆栈,驻留常规RAM区域,速度仅次于寄存器。对象句柄保存在堆栈中。
③堆,一种常规用途的内存池(在RAM中)。灵活性高于堆栈,但是性能低(堆内分配存储空间时间更长),JAVA对象保存在此区域。
④静态存储,位于RAM中。static关键字指出一个对象的特定元素是静态的。但JAVA对象本身永远不会置入静态存储区。
⑤常数存储,位于只读存储(ROM)。保存常数值
⑥非RAM存储,流式对象或固定对象。
2.2.2 主要类型
又称为基本类型,主要包括:boolean,char,byte,short,int,long,float,doule,void
对于这些类型,不是通过new创建变量,而是创建一个并非句柄的“自动”变量,这个变量容纳了具体的值。位于堆栈中。
主类型都有自己的包装类
主类型 | 大小 | 最小值 | 最大值 | 封装器类型 |
boolean | 1 | - | - | Boolean |
char | 16 | 0 | 2^16 - 1 | Character |
byte | 8 | -128 | 127 | Byte |
short | 16 | -2^15 | 2^15-1 | Short |
int | 32 | -2^31 | 2^31-1 | Integer |
long | 64 | -2^63 | 2^63-1 | Long |
float | 32 | IEEE754 | IEEE754 | Float |
double | 64 | IEEE754 | IEEE754 | Double |
另外,BigInteger,BigDecimal也可以属于封装器类型,但并没有对应的基本类型。
BigInteger支持任意精度的整数,BigDecimal支持任意精度的定点数。
2.2.3 JAVA中的数组
对象数组,实际创建的是句柄数组。每个句柄都会被初始化为一个特殊值,并带有关键字null.null表示句柄并没有指向一个对象。
Sring[] s = new String[4];
我们创建了一个大小为4的String数组,s[0]—>s[3]都为null,并未指向对象。
基本类型数组,int[] i = new int[4];
编译器担保对它的初始化 i[0]—>i[3] 都为0
2.3 绝对不要清除对象
2.3.1 作用域
作用域通过花括号的位置决定。花括号结束,其内部的基本类型变量不可见(无法访问),变量空间(堆栈)释放。对于Java对象类型,句柄变量(堆栈)同样不可见(无法访问),但是句柄指向的对象空间仍然存在(堆区)。那么这些对象空间如何释放呢? Java采用垃回收器(GC)进行处理,释放那些不再被引用的对象空间。
举例:
句柄s1指向的java对象,在句柄s1消亡之前,通过句柄s1传递给句柄s2。最后虽然句柄s1消亡了,但是其指向的对象仍然存在,可以通过句柄s2继续访问。当s2退出作用域消亡后,此对象就没有句柄引用,GC会在适当的时间进行回收,程序员不需要手动编写程序释放堆空间中的对象内存空间。
{ int x = 12; String s2 = null; { int q = 96; x = 10; String s1 = new String("scope"); s2 = s1; } /* q out of scope */ /* s1 out of scope*/ x = 12; System.out.println(s2); }
2.4 新建数据类型:类
新建类:class ATypeName {/*类主体置于这里} 创建对象:ATypeName a = new ATypeName();
2.4.1 字段和方法
每个类可设置两种类型的元素:成员变量(字段)和成员方法(方法)
成员变量可以是基本类型(非句柄)也可以是JAVA对象(通过句柄与其通信);初始化方式:定义位置初始化和构造函数初始化。
每个对象为自己的成员变量有存储空间,成员变量不会在对象之间共享。
如果成员变量是基本类型,即使不显示初始化,编译器也会分配默认值(作为类中的成员变量可以,如果是局部变量必须手动初始化)。如下图所示:
class A{ boolean bo; char c; byte by; short s; int i; long l; float f; double d; } public class test { public static void main(String[] args){ A a = new A(); System.out.println("boolean类型默认值为:" + a.bo); System.out.println("char类型默认值为:" + Integer.toHexString(a.c)); System.out.println("byte类型默认值为:" + a.by); System.out.println("short类型默认值为:" + a.s); System.out.println("int类型默认值为:" + a.i); System.out.println("long类型默认值为:" + a.l); System.out.println("float类型默认值为:" + a.f); System.out.println("double类型默认值为:" + a.d); } }
结果为:
boolean类型默认值为:false
char类型默认值为:0
byte类型默认值为:0
short类型默认值为:0
int类型默认值为:0
long类型默认值为:0
float类型默认值为:0.0
double类型默认值为:0.0
2.5 方法、自变量和返回值
非静态方法必须用对象进行调用,静态方法可针对类调用。
2.5.1 自变量列表
方法调用参数传递时,基本类型传递的是值,非基本类型传递的是句柄。
2.6 构建JAVA程序
2.6.1 名字的可见性
C++ 采用命名空间。JAVA采用了包或类库 com.ouc.telcom类似形式
2.6.2 使用其他组件
import java.util.Vector ;import java.util.*;
2.6.3 static关键字
一旦将什么东西设置为static,数据或方法就不会同那个类的任何对象关联到一起,也就是说不用创建对象,仍可以调用static方法或者访问static变量。
非static方法既可以调用非static方法,访问非static变量。也可以调用static方法,访问static变量。
static方法只能够调用static方法,访问static变量。
2.7 我们的第一个JAVA程序
程序文件开头,import语句导入额外的类。java.lang这个特殊的类会自动导入每一个java文件
2.8 注释和嵌入文档
方式一: /*注释内容*/
方式二://单行注释
文档注释格式:/**文档注释*/
提取注释的工具javadoc javadoc输出的是HTML文档
javadoc只能够为public以及protected成员处理注释