首页 > 代码库 > Java之路(一) 一切皆对象
Java之路(一) 一切皆对象
Java语言假设我们只进行面向对象的程序设计,即在开始用Java进行设计前,我们需要将思想切换到面向对象的世界中。
1.用引用操纵对象
每种编程语言都有自己操纵内存中元素的方式。是直接操纵元素还是用某种基于特殊语法的间接表示来操纵对象?
Java中将一切都视为对象,这样就可采用较为单一固定的语法。
虽然将一切都看做对象,但操纵的标识符实际上是对象的引用。
拥有一个引用,并不一定与一个对象相关联。
2.必须由使用者创建所有对象
1).Java内存分配
五个地方可以存储数据:
a.寄存器。位于处理器内部,速度最快,但数量有限,不能直接控制。
b.堆栈。位于RAM中,通过堆栈指针可以从处理器那里获得直接支持。速度仅次于寄存器。
但Java系统必须知道存储在堆栈的所有项的声明周期,这样才能操纵堆栈指针分配或者释放内存。
对象引用存储在堆栈中(堆栈还存储着其他项),但对象不存储在堆栈中。
c.堆。位于RAM区,一种通用的内存池,存放所有的Java对象。编译器不需要知道存储在堆里的数据的存活时间。速度慢于堆栈。
d.常量存储。常量值通常存于程序代码内部。
e.非RAM存储。如持久化对象,数据存储在磁盘上。
2).一切皆是对象的特例:基本类型
new创建对象存放在堆上,但创建简单、较小的变量用没有必要用new。因此Java采用创建并非是引用的自动变量来存储这类小而简单的变量,并将它们放在堆栈里,以提高效率。这类自动变量就是Java的基本类型。
基本类型共9种,如下表所示:
基本类型 | 大小 | 最小值 | 最大值 | 包装器类型 |
boolean | — | — | — | Boolean |
char | 16-bit | 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 |
从表中可知基本类型的特点:占用存储空间大小不变;所有数值类型都是有符号数;具有包装器。
占用存储空间大小不变提高了Java程序的可移植性。
Java中一切皆对象,但基本类型却不是对象,为了解决这个为题,Java对每个基本类型都对应了一个引用的类型,称为包装器类型。
包装器类型将基本类型包装起来,添加了属性和方法。Java SE5自动包装功能可以将基本类型转换为包装器类型,当然也可以反向转换。
基本类型和它们的包装器类型有哪些区别呢?
a)包含内容不同。基本类型只是表示一个数据,包装器类型包括数据和方法。
b)声明方式不同。包装器类型需要使用new来声明,而基本类型不需要。
c)未进行初始化时,默认初始值不同。如int作为类成员变量时,默认初始值为0,而包装器类型都为null。
d)存储位置不同。基本类型存储在堆栈中,而包装器类型的引用存储在堆栈中,引用引用的对象存储在堆中。
e)使用方式不同。基本类型可以直接赋值,不能放进List,Map等集合类中,而包装器类型可以。
Java还提供了两个用于高精度计算的类,BigInteger(支持任意精读的整数)和BigDecimal(支持任何精度的定点数)。它们大体上属于包装器类型,但没有对应的基本类型。
3).数组
Java会确保数组被初始化,不能在范围之外被访问。这提高了安全性和效率,但也意味着要对数组进行范围检查,而且需要额外的内存开销。
创建基本类型的数组时,所有元素都会被初始化为0。
创建一个数组对象时,实际上创建的是引用数组,所有元素都被初始化为null。使用null的引用运行时会报错。
3.不需要销毁对象
当要销毁一个对象时,就要考虑它的存活时间和销毁的恰当时间。
1).基本变量与作用域
作用域决定了定义在其内的变量的可见性和存活时间,在作用域里定义的变量只存活在作用域里。
但要注意,Java不支持作用域的变量隐藏,如下:
{ int a=1; { int a=2; //非法 } }
2).对象的作用域
对象不具备和基本类型一样的声明周期,在作用域内用new创建的对象可以存活到作用域之外。如下:
{ String s = new String("a string"); }
应用s在{}外不再存在,而其指向的String仍然存在并占用着内存空间,但是我们无法在访问这个对象了。这个String何时被销毁由垃圾回收器确定,当垃圾回收器确定它不会再被引用时,就会释放它占用的内存。
4.类的字段
class DataOnly{ //class 定义类的关键字 DataOnly类名 类中包含字段和方法 int i; //字段可以是基本类型 double d; //普通字段不能在对象间共享 boolean b;//字段可以是任何类型的对象,可以通过引用与其进行通信//字段是某个对象的引用时,必须初始化}
基本成员默认值
若类的某个成员是基本数据类型时,如果没有进行初始化,Java会给其一个默认值。默认值如下表:
基本类型 | 默认值 |
boolean | false |
char | ‘\u0000‘(null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0L |
double | 0.0d |
注意:只有当基本类型变量作为类的成员时,Java才会确保给其默认值。
不是类的成员时,不会自动初始化。这时如果不赋值,编译时报未初始化错误。
5.类的方法
方法就是函数。Java的方法决定了一个对象能够接收什么样的消息。方法签名(方法名和参数列表合起来)唯一的表示出某个方法。
方法的参数列表指定要传递给方法什么样的消息,这些信息以对象形式传递,且实际传送的是对象的引用。
6.static关键字
static关键字可以满足两种情形:一是只想为某特定域分配电一存储空间,而不去考虑究竟要创建多少对象,甚至根本就不需要创建任何对象;二是希望某个方法不与包含它的类的任何对象关联在一起,即即使没有创建对象也可以调用这个方法。
当声明一个事物为static时,就以为这这个域或方法不会与包含它的那个类的任何对象实例关联在一起。所以,即使从未创建某个类的任何对象,也可以调用其static方法或访问其static域。
static变量和方法有两种引用方式:一是通过创建类的对象,使用对象来引用;二是直接通过类名来引用。
7.第一个Java程序
1 //HelloDate.java2 import java.util.*;3 public class HelloDate{4 public static void main(String[] args){5 System.out.println("Hello, it‘s ");6 System.out.println(new Date());7 }8 }
第2行引入Date类。注意,在Java的所有文件中,都会自动导入java.lang类库。
第3行定义了一个HelloDate类,是public的。
第4行的main()函数必须存在,编译器要求args也必须存在,因为要用来存储命令行参数。mian()函数是static的,它是运行一个应用时的入口点。
第5行的out是一个静态的PrintStream类,因为是静态,不需要创建任何对象,out便已经存在了,可以直接使用;out类可调用的方法由其类型PrintStream决定,如可以使用println()方法打印传入的数据到控制台,并换行。out是静态的,使用完后依然存在。
第6行的new Date()创建了一个Date对象,并将其值转换为String类型发送给println()。之后Date对象可以随时被垃圾回收器销毁。
Java之路(一) 一切皆对象