新建一个对象的,数据存储的位置可能不一样;JAVA存放数据的地方有:
程序运行时,我们最好对数据保存到什么地方做到心中有数。特别要注意的是内存的分配。有六个地方都可以保存数据:
(1) 寄存器。这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由编译器分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。
(2) 堆栈。驻留于常规RAM(随机访问存储器)区域,但可通过它的“堆栈指针”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那 些内存。创建程序时,Java编译器必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动 指针。这一限制无疑影响了程序的灵活性,所以尽管有些Java数据要保存在堆栈里——特别是对象句柄,但Java对象并不放到其中。
(3) 堆。一种常规用途的内存池(也在RAM区域),其中保存了Java对象。和堆栈不同,堆(Heap)中编译器不必知道要从堆里分配多少存储空间,也不必知 道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码 时,会在堆里自动进行数据的保存。在堆里分配存储空间时会花掉更长的时间!
(4) 静态存储。这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。
(5) 常数存储。常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入只读存储器(ROM)。
(6) 非RAM存储。 不研究;
其中,堆和栈是两个最常用的,每种语言都用到.而且不同语言对堆和栈的理解和数据结构里的定义可能不同.
实际上,变量也是一种对象,是语言的原始对象.我们也可以自定义自己的对象.当我们声明对象的时候,内在就会开辟一片空间来存储数据.如果声明的是长度已知的对象,则会在栈中存储,如果不可知,则在堆中.
boolean |
1-bit |
– |
– |
Boolean |
char |
16-bit |
Unicode 0 |
Unicode 216 - 1 |
Character |
byte |
8-bit |
-128 |
+127 | |
short |
16-bit |
-215 |
+215 – 1 |
Short1 |
int |
32-bit |
-231 |
+231 – 1 |
Integer |
long |
64-bit |
-263 |
+263 – 1 |
Long |
float |
32-bit |
IEEE754 |
IEEE754 |
Float |
double |
64-bit |
IEEE754 |
IEEE754 |
Double |
void |
– |
– |
– |
Void 1 |
上面这些是可知的对象,第二列是在内在中占的位置.再后面两列是该对象值的边界.
上面这些类型的对象若用new声明,则程序会自动给它赋一个默认值:
Boolean abc = new Boolean();这时候程序会给abc默认为:false;
默认值为:
boolean false;
char '\u0000'(null)
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
假若在一个函数定义中写入下述代码:
int x;
那么x会得到一些随机值(这与C和C++是一样的),不会自动初始化成零。我们要在正式使用x前分配一个适当的值。如果忘记,就会得到一条编译期错误,告诉我们变量可能尚未初始化。
JAVA中String类未固定大小,所以声明的时候是放在堆中,但在JavaScript中,则是放在栈中的.
再就是:用 new()声明的对象,其数据都是放在堆中的,栈中存放的是指向该数据的"句柄".
声明的对象有自己的存在时间(Life Time);
{
int x = 12;
{
int q = 96;
}
}
在JAVA中,不能让同一个变量或者用同一个名称定义变量,在不同的范围.
{
int x = 12;
{
int x = 96;
}
}
句柄s会在作用域的终点处消失。然而,s指向的String对象依然占据着内存空间。在上面这段代码里,我们没有办法访问对象, 因为指向它的唯一一个句柄已超出了作用域的边界。这样造成的结果便是:对于用new创建的对象,只要我们愿意,它们就会一直保留下去。怎样才能防止它们大 量充斥内存,并最终造成程序的“凝固”呢。在C++里,这个问题最令程序员头痛。但Java以后,情况却发生了改观。Java有一个特别的 “垃圾收集器” ,它会查找用new创建的所有对象,并辨别其中哪些不再被引用。随后,它会自动释放由那些闲置对象占据的内存,以便能由新对象使用。这样就可以防止"内存溢出".
声明一个对象的时候实际上是在堆中开辟一块空间存放数据,然后在栈中放一个指向这块空间的"句柄".所以,若一个对象未被初始化,则句柄就不知道指向哪里,所以就会被默认赋个定值:null;若使用一个还是null的句柄,会出错.所以,声明变量的时候都要进行初始化.
特例是:原始类型(也叫基本类型) 声明的时候,是直接放在栈中的.而且编译器会自动赋初值.但这又分两种情况,一种是该类型的对象是在 类中作为"属性" 存在,这时候编译器赋的初始值如下表:
boolean false;
char '\u0000'(null)
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d
另一种情况就是非对象的属性,这时候编译器赋的值可能出错;如下:
int x;这时候x的值可能是一个随机值;
Java允许我们把任何基本数据类型的变量转换成别的基本数据类型,但布尔值除外,布尔值不允许任何类型的转换."类"本身,是不允许转换的.一个对象可以在所属类族之间进行转换.如:桃树,可以转换成树.反之也可以,但不能转换成石头.