在Java中,创建一个对象通常都用new关键字,并且需要创建一个引用来跟这个对象相关联,该引用就是实际操纵其相关联对象的标识符。如下:
在这里创建的仅仅是引用并不是对象(安全的做法:在创建一个引用的同时便对其进行初始化)
Java对象的主要存储地方:
[b]堆栈——简称"栈",用于存储对象的引用,基于堆栈指针存储、移除数据[/b]
【优势】存储速度快,仅次于寄存器,栈数据可以共享。
【不足】编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,缺乏灵活性。
主要存储基本类型(boolean、char、byte、short、int、long、float、double)和对象句柄。
【[i]注意[/i]】[u]String不是基本类型,是类。不过String类在java中比较特殊,被设计成为不可改变(immutable)的类,封装了有关字符串的操作,字符串是创建后就不可改变的;可变的对应是StringBuffer类。[/u]
1.数据共享
2.对象引用共享
【[i]注意[/i]】[u]数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,它是由编译器完成的,有利于节省空间;而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。[/u]
[b]堆——用于存储所有的Java对象[/b]
【优势】编译器不需要知道数据存储块内存分配大小和生命周期,具有很大的灵活性。可以动态分配内存大小,且Java垃圾收集器会自动收回无用的数据。
【不足】由于要在运行时动态分配内存,存储速度较慢。
【[i]注意[/i]】[u]我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。[/u]
String s;
在这里创建的仅仅是引用并不是对象(安全的做法:在创建一个引用的同时便对其进行初始化)
String s = "asdf";
Java对象的主要存储地方:
[b]堆栈——简称"栈",用于存储对象的引用,基于堆栈指针存储、移除数据[/b]
【优势】存储速度快,仅次于寄存器,栈数据可以共享。
【不足】编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,缺乏灵活性。
主要存储基本类型(boolean、char、byte、short、int、long、float、double)和对象句柄。
【[i]注意[/i]】[u]String不是基本类型,是类。不过String类在java中比较特殊,被设计成为不可改变(immutable)的类,封装了有关字符串的操作,字符串是创建后就不可改变的;可变的对应是StringBuffer类。[/u]
1.数据共享
/*
创建了一个对象变量为a的引用,编译器首先在栈中查找是否有3这个值
if(!has 3){
把3这值存储到栈中,并使引用a指向该值;
}
*/
int a = 3;
/*
接着创建一个对象变量为b的引用,同样先查找栈中是否有3这个值
if(has 3){
把引用b指向a所指向的值3;
}
*/
int b = 3;
System.out.println(a==b);//true
/*
根据以上情况,引用a和b在栈中指向同一值,故此这两个变量相等,同时也证明了栈中共享数据。如果此时改变变量a的值,那么其引用的指向也会随之改变。也就是说编译器会重新查找栈,检查数据。那么下面变量a的引用就指向新的地址,其引用的改变不会影响变量b的引用指向。
*/
a = 4;
System.out.println(a==b);//false
2.对象引用共享
/*
String是一个特殊的包装类数据,其包括两种创建方式:
1).在栈中创建一个对String类的对象引用变量str,然后查找栈中是否存放"abc"。没有,则将"abc"存放进栈,并令str指向”abc”;再创建另一个对String类的对象引用变量s1、s2指向str这同一引用对象,查找栈中是否存放"abc"。有"abc" 则直接令s1、s2指向"abc"。
*/
String str = "abc";
String s1 = str;
String s2 = str;
System.out.println(s1==s2);//true
System.out.println(s1.equals(s2));//true
//从上面可以看到,s1和s2指向同一对象。
【[i]注意[/i]】[u]数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,它是由编译器完成的,有利于节省空间;而一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量。[/u]
[b]堆——用于存储所有的Java对象[/b]
【优势】编译器不需要知道数据存储块内存分配大小和生命周期,具有很大的灵活性。可以动态分配内存大小,且Java垃圾收集器会自动收回无用的数据。
【不足】由于要在运行时动态分配内存,存储速度较慢。
/*
2).用关键字new来创建新对象,它会在存放于堆中。每调用一次就会创建一个新的对象。在堆中创建新对象时,都是不管其字符串值是否相等、是否有必要创建新对象,从而加重了程序的负担。
*/
String a = new String("abc");
String b = new String("abc");
System.out.println(a==b);//false
System.out.println(a.equals(b));//true
/*
故上述说明,存放在堆里不同内存块中的两个对象不能用"=="相比较。比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用"=="。
*/
【[i]注意[/i]】[u]我们在使用诸如String str = "abc";的格式定义类时,总是想当然地认为创建了String类的对象str。担心陷阱!对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。[/u]