-
2.1 特例:基本类型
- 基本类型是一个并非是引用的“自动”变量。这个变量直接存储“值”,并置于堆栈中,因此更加高效。Java的基本类型所占存储空间大小不随机器硬件架构的变化而变化。这种所占存储空间大小的不变性是Java程序比用其他大多数语言编写的程序更具可移植性的原因之一。
-
基本类型 大小 最小值 最大值 包装器类 boolean – – – Boolean byte 8 bits -128 +127 Byte char 16 bits Unicode 0 Unicode 216-1 Character short 16 bits -215 +215-1 Short int 32 bits -232 +232-1 Integer float 32 bits IEEE754 IEEE754 Float long 64 bits -263 +263-1 Long double 64 bits IEEE754 IEEE754 Double void – – – Void - 所有数值类型都有正负号
- boolean类型所占存储空间的大小没有明确指定(要看具体虚拟机的实现),仅定义为能够取字面值true或false。
-
2.2 Java中的数组
- Java确保数组会被初始化。而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价的。
-
《深入理解Java虚拟机》: Java 语言中对数组的访问比C/C++相对安全是因为:如有一维数组,其元素类型为
mypackage.MyClass
,则虚拟机会自动生成一个直接继承于java.lang.Object
的子类[Lmypackage.MyClass
,创建动作由字节码指令newarray
触发。这个类代表了一个元素类型为mypackage.MyClass
的一维数组,数组中应有的属性和方法(用户可直接使用的只有被修饰为public的length
属性和clone()
方法)都实现在这个类里。Java语言中对数组的访问比C/C++相对安全就是因为这个类封装了数组元素的访问方法(准确地说,越界检查不是封装在数组元素访问的类中,而是封装在数组访问的xaload
、xastore
字节码中),而C/C++直接翻译为对数组指针的移动。 - 数组对象,实际就是一个引用数组,每个元素会被初始化为null。
- 基本数据类型的数组,编译器会将这种数组所占的内存全部置为零。
- 在Java语言中,当检查到发生数组越界时会抛出
java.lang.ArrayIndexOutOfBoundsException
异常。
-
2.3 作用域(scope)
-
Java 与 C/C++ 关于作用域的区别:如下,对于Java,非法,而对于 C/C++ 合法。(在 C/C++ 里将一个作用域的变量“隐藏”起来的做法,在Java里是不允许的。因为Java设计者认为这样做会导致程序混乱。)
{ int x = 12; { int x = 96; // Illegal for Java, but legal for C/C++ } }
- Java对象不具备和基本类型一样的生命周期。当用new创建一个Java对象时,它可以存活于作用域之外。如:
{ String s = new String("a string"); } // End of scope
引用
s
在作用域终点就消失了。然而,s
指向的 String 对象仍继续占据内存空间。
-
-
2.4 import 关键字
- import关键字指示编译器导入一个包,也就是一个类库(在其他语言中,一个库不仅包含类,还可能包括方法和数据,但是Java中所有的代码都必须写在类里)。
- 特定类
java.lang
会被自动导入到每一个Java文件中。
-
2.5 static 关键字
-
2.5.1 通过 static 关键字可以满足以下两方面情形的需要:
- 只想为某一特定域分配单一存储空间,而不去考虑空间要创建多少对象,甚至根本就不创建任何对象。
- 希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用这个方法。
有些面向对象语言采用类数据和类方法两个术语,代表那些数据和方法只是作为整个类,而不是类的某个特定对象而存在的。例:
-
2.5.2 static 字段
-
class StaticTest{ static int i = 47; }
- 如下创建两个对象,st1.i 和 st2.i 指向同一存储空间,共享同一个
i
,因此它们具有相同的值47。StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest();
-
- 2.5.3 static 方法
static
作用于字段时,会改变数据的创建方式,但作用于方法时,差别却没有那么大。static
方法的一个重要用法就是在不创建任何对象的前提下就可以调用它。这一点对定义main()
方法很重要(所以main()
方法是一个 satic 方法),这个方法是运行一个应用时的入口点。- 和其它任何方法一样,
static
方法可以创建或使用与其类型相同的被命名对象,因此,static
方法常常拿来做“牧羊人”的角色,负责看护与其隶属同一类型的实例群。 static
方法的含义:static
方法就是没有this
的方法。关于static方法内部是否能调用非静态方法:因为没有this
,就没有对象,所以不能直接调用非静态方法,但可以传递一个对象引用到静态方法里,然后通过这个引用(和this
效果相同)来调用非静态方法和访问非静态数据成员。- 有些人认为
static
方法不是“面向对象”的,因为它们的确具有全局函数的语义;使用static
方法时,由于不存在this
,所以不是通过“向对象发送消息”的方式来完成的。
-