<转>String的==和equals区别, JAVA中的堆与栈

Java 中的堆和栈
Java把内存划分成两种:一种是栈内存,一种是堆内存.
1. 在函数中定义的一些基本类型的变量,对象的引用变量,都在函数的栈内存中分配
   当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间.

2. 堆内存用来存放由new创建的对象和数组
   新创建的对象和数组存放在堆内存中.不过它们的引用变量存放在栈内存中,这个变量的值等于数组或对象在堆内存中的首地址.

3. 栈的优点缺点
   栈的优势是,存取速度很快,仅次于寄存器;栈数据可以共享(后面会详细介绍);这些决定了栈内存中主要存放一些基本类型的变量(int, short, byte, char, double...)以及对象引用.
   缺点是,存在栈中的数据大小与生存周期必须在编译时就确定.

4  堆的优点缺点
   堆是一个运行时数据区,优势是可以动态地分配内存大小,生存期也不必事先告诉编译器;缺点是存取速度较慢.

5  栈的一个重要特征: '数据共享'
   存在栈中的数据可以共享,假设我们同时定义:

  
Java代码
  1. int  a =  3 ;   
  2. int  b =  3 ;  
int a = 3; 
int b = 3;


   编译器先处理int a = 3;首先它会在栈中创建一个变量为a的引用,然后查找栈中是否有3这个值,如果没找到,就将3存进来,然后将a指向3.接着处理int b = 3:在创建完变量为b的引用变量后,因为在栈中已经有3这个值,便将b直接指向3.这样就出现了a与b同时均指向3的情况.这时,如果再令a=4,那么编 译器会重新搜索栈中是否有4值,如果没有,则将4存放进来,并令a指向4;如果已经有了,则直接将a指向这个地址.因此a值的改变不会影响到b的值.要注 意这种数据的共享与两个对象的引用同时指向一个对象的这种共享是不同的,因为这种情况a的修改并不会影响到b,它是由编译器完成的,它有利于节省空间.而 一个对象引用变量修改了这个对象的内部状态,会影响到另一个对象引用变量.

6  String中的equals()和==
   可以用两种方式来创建一个String对象:

  
Java代码
  1. String str =  new  String( "abc" );   
  2. String str = "abc" ;      
String str = new String("abc"); 
String str = "abc";    


  第一种是用new()来新建对象的,它会在存放于堆内存中.每调用一次就会创建一个新的对象;而第二种是先在栈中创建一个引用变量str,然后查找栈中有 没有存放'abc',如果没有,则将'abc'存放进栈,并令str指向'abc';如果已经有'abc',则直接令str指向'abc';
   比较类里面的数值是否相等时,用equals()方法;当测试两个包装类的引用是否指向同一个对象时,用==.下面用例子说明上面的理论.

  
Java代码
  1. String str1 =  "abc" ;   
  2. String str2 = "abc" ;   
  3. System.out.println(str1==str2); //true    
String str1 = "abc"; 
String str2 = "abc"; 
System.out.println(str1==str2); //true 


   可以看出str1和str2是指向同一个对象的.

 
Java代码
  1. String str1 = new  String ( "abc" );   
  2. String str2 =new  String ( "abc" );   
  3. System.out.println(str1==str2); // false    
String str1 =new String ("abc"); 
String str2 =new String ("abc"); 
System.out.println(str1==str2); // false 


   用new的方式是生成不同的对象,每一次生成一个.因此用第二种方式创建多个'abc'字符串,在内存中其实只存在一个对象而已.这种写法有利与节省内存 空间.同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象.而对于String str = new String("abc")的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担.
  最后附上几个实例比较,打印结果自己跑一下就知道了,:)

Java代码
  1. String a = "abc" ;  
  2. String b ="abc" ;  
  3. String c = new  String ( "abc" );  
  4. System.out.println(a==b);  
  5. System.out.println(a.equals(b));  
  6. System.out.println(a==c);  
  7. System.out.println(a.equals(c));  
  8. System.out.println(System.identityHashCode(a)); //打印的是内存的地址(可以这么认为!)   
  9. System.out.println(System.identityHashCode(b));   
  10. System.out.println(System.identityHashCode(c));     
  String a ="abc";
  String b ="abc";
  String c = new String ("abc");
  System.out.println(a==b);
  System.out.println(a.equals(b));
  System.out.println(a==c);
  System.out.println(a.equals(c));
  System.out.println(System.identityHashCode(a)); //打印的是内存的地址(可以这么认为!)
  System.out.println(System.identityHashCode(b)); 
  System.out.println(System.identityHashCode(c));   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值