复习 J2SE基本内容 常量池问题

数据的三种存放方式

1. 直接存放入常量池

String s = "123" ;

2.直接存入常量池 ,并在堆中创建存储空间  

String s = new String("123") ;

3.123,456直接放进常量池,当调用String.intern方法时,字符串123456才进入常量池,否则123456永远不进入常量池。

String str = new StringBulider("123").append("456").toString(); 

String.intern方法是一个Native方法,作用是:如果常量池中已经存在此String对象的字符串,则返回此对象在常量池中的地址值;否则,将此字符串的地址值添加到常量池中,并返回此地址值(jdk1.7以后的)。

字符类型的 == 关系

例题2 
String s1 = "abcd" ;
String s2 = "abcd" ;
String s3 = "ab"+ "cd" ;
String s4 = new String("abcd") ;
String s5 = "ab" + new String("cd") ;
System.out.println( s1 == s2 ) ;
System.out.println( s2 == s3 ) ;
System.out.println( s2 == s4 ) ;
System.out.println( s2 == s5 ) ;
System.out.println( s4 == s5 ) ;

结果为:

true          s1==s2 无争议 

true           s2==s3 因为s3由字符类型构成 字符类型相同 所以相等

false          用new String() 创建的字符串不是常量,new String() 创建的字符串不放入常量池中,它们有自己的地址空间

false          因为有后半部分 new String(”cd”)   new String() 创建的字符串不放入常量池中

false          因为有后半部分 new String(”cd”) new String() 创建的字符串不放入常量池中

特殊存在时候的 == 关系

  String a = "a1" ;

  String b = "a" + 1 ;

  System.out.println(( a == b )) ; 


  String a = "ab" ;

  String bb = "b" ;

  String c = "a" + bb ;

  System.out.println(( a == b )) ; 


  String a = "ab" ;

  final String bb = "b" ;

  String b = "a" + bb ;

  System.out.println(( a == b )) ; 


  

结果是:

true            字符串常量的"+“号连接

false            在字符串的"+“连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的 ,只有在程序运行期来动态分配并将连接后的新地址赋给b

ture            bb字符串加了final修饰,对于final修饰的变量,,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。
 


  final StringBuffer a = new StringBuffer("111");

  final StringBuffer b = new StringBuffer("222");

  a=b;//此句编译不通过

  final StringBuffer a = new StringBuffer("111");

  a.append("222");// 编译通过

final只对引用的"值"(即内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象 的变化,final是不负责的。

 

Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);

System.out.println("i1=i2\t" + (i1 == i2));
System.out.println("i1=i2+i3\t" + (i1 == i2 + i3));
System.out.println("i4=i5\t" + (i4 == i5));
System.out.println("i4=i5+i6\t" + (i4 == i5 + i6));

System.out.println();

结果为 :

true       Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现

true

false

ture       进行了重写实现加减

String s1 = "abc";
String s2 = "abc";
System.out.println(s1.equals(s2));
System.out.println(s1 == s2);

为什么第二个会是true呢?
这就涉及到了内存中的常量池,常量池属于方法区的一部分,当运行到s1创建对象时,如果常量池中没有,就在常量池中创建一个对象"abc",第二次创建的时候,就直接使用,所以两次创建的对象其实是同一个对象,它们的地址值相等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值