String相关问题小结

 Java面试中总喜欢出几个关于String对象的题,比如:

1.String s = new String("abc");创建了几个String对象。

2.String s1 = "abc";
   String s2 = "a";
   String s3 = s2 + "bc";
   String s4 = "a" + "bc";
   String s5 = s3.intern();
请问s1==s3是true还是false,s1==s4是false还是true。s1==s5呢?

首相我们知道,字符串是常量;它们的值在创建之后不能更改。因为 String 对象是不可变的,所以可以共享(String类自己维护了一个池,把程序中的String对象放到那个池里面,于是我们代码中只要用到值相同的String,就是同一个String对象,节省了空间);但是,并不是任何时候任何String对象都在这个字符串池中。

首先解释下什么是字符串字面常数(String Literals),字面常数(Literals)就是你写在源代码里面的值,比如说int i = 6; 6就是一个整数形字面常数。String s = "abc"; “abc”就是一个字符串字面常数。Java中,所有的字符串字面常数都放在上文提到的字符串池里面,是可以共享的,就是说,String s1 = "abc"; String s2 = "abc"; s1,s2都引用的同一个字符串对象,而且这个对象在字符串池里面,因此s1==s2。另外,字符串字面常数是什么时候实例化并放到字符串池里面去的呢?答案是Load Class的时候

在程序运行时通过连接(+)计算出来的字符串对象,是新创建的,他们不是字面常数,就算他们值相同,他们也不在字符串池里面,他们在堆内存空间里,因此引用的对象各不相同。

因此:第一题答案是创建了两个对象,一个是字符串字面常数,在字符串池中。一个是new出来的字符串对象,在堆中。第二题:因为s2是一个变量,所以s3是运行时才能计算出来的字符串,是new的,在堆中不在字符串池中。s4是通过常量表达式计算出来的,他等同于字符串字面常数,在字符串池中。所以,s1!=s3,s1==s4。再看s5,s5是s3放到字符串池里面返回的对像,所以s1==s5。这里新手要注意的是,s3.intern()方法,是返回字符串在池中的引用,并不会改变s3这个变量的引用,就是s3还是指向堆中的那个"abc",并没有因调用了intern()方法而改变,实际上也不可能改变。

那么什么是常量表达式呢?

记住一个原则就好了,那就是编译时能确定的,就算,运行时才能确定的,就不算。以下为例子

String s = 1 + "23";//算,符合第二条Casts to primitive types and casts to type String
String s = (2 > 1) + "" ;//算,意味着s=="true",且这个“true”已经放到字符串池里面去了。
String s = (o instanceof Object) + "";//不算,instanceof这个操作符决定了不算。s=="true",但这个"true"对象在堆中。

留意下面的情况。

   final String s2 = "a";
   String s3 = s2 + "bc";//算

注意现在的s2+"bc"也算一个常量表达式,理由是那个列表里面的最后两条,s2是一个常量变量(constant variables),问题又来了,什么是常量变量?规范里也说了,被final修饰,并且通过常量表达式初始化的变量,就是常量变量。变量s2被final修饰,他通过常量表达式"a"初始化,所以s2是一个常量变量,所以s3引用的"abc",也在字符串池里面。

再举个反例:

final String s2 = getA();//s2不是常量变量,但是s2引用的"a"其实还是在常量池中,这两点不矛盾
public String getA(){return "a"}

String s3 = s2 + "bc";//此时s3不算常量表达式,因为s2不是常量变量

这是时候的s2,就不是常量变量了哦,因为getA()不是一个常量表达式

3.常用的两个方法:

lastindexof("/");  / 找到所要找的字符的位置的下标

substring(2);        / 获取下标是2的以后(从左向右)的字符值

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值