java实现string_Java中String的实现与应用

public final class String implements java.io.Serializable,Comparable, CharSequence {

privatefinalchar value[];

privateinthash;

}

String其实是对一个char数组的封装。提供了各种操作方法。值得注意的是这个数组的final的,也就是这个引用是不可变的。注意是引用,数组中每一项的值理论上是可以改变的,比如通过反射,但是不推荐这么做。

关于String有一些有趣的地方:

package terry.java.base;

publicclass StringTest {

publicstaticvoid main(String[] args) {

String a = "hello";

String b = "hello";

String newA = new String("hello");

String newB = new String("hello");

System.out.println("****** Testing Object == ******");

System.out.println("a==b ? :" + (a==b));

System.out.println("newA==newB ? :" +(newA==newB));

System.out.println("a==newA ? :" + (a==newA));

System.out.println("***** Testing String Object intern method******");

System.out.println("a.intern()==b.intern() ? : " + (a.intern()==b.intern()));

System.out.println("newA.intern()==newB.intern() ? :" + (newA.intern()==newB.intern()));

System.out.println("a.intern()==newA.intern() ? :" + (a.intern()==newA.intern()));

System.out.println("a=a.intern() ? :" + (a==a.intern()));

System.out.println("newA==newA.intern() ? : " + (newA==newA.intern()));

System.out.println("****** Testing String Object equals method******");

System.out.println("equals() method :" + a.equals(newA));

String c = "hel";

String d = "lo";

final String finalc = "hel";

final String finalgetc = getc();

System.out.println("****** Testing Object splice ******");2 System.out.println("a==\"hel\"+\"lo\" ? :" + (a=="hel"+"lo"));

System.out.println("a==c+d ? : " + (a==c+d));

System.out.println("a==c+\"lo\" ? : " + (a==c+"lo"));

System.out.println("a==finalc+\"lo\" ? :" + (a==finalc+"lo"));

System.out.println("a==finalgetc+\"lo\" ? :" + (a==finalgetc+"lo"));

}

privatestatic String getc(){

return"hel";

}

}

输出:

****** Testing Object == ******

a==b ? :true

newA==newB ? :false

a==newA ? :false

***** Testing String Object intern method******

a.intern()==b.intern() ? : true

newA.intern()==newB.intern() ? :true

a.intern()==newA.intern() ? :true

a==a.intern() ? :true

newA==newA.intern() ? : false

****** Testing String Object equals method******

equals() method :true

****** Testing Object splice******

a=="hel"+"lo" ? :true

a==c+d ? : false

a==c+"lo" ? : false

a==finalc+"lo" ? :true

a==finalgetc+"lo" ? :false

这里可能一些不太容易理解的地方。首先介绍一个常量池的概念。String维护了一个字符串的常量池,当用String a = "hello"这种方式时,首先创建一个String类型的引用a,然后到常量池中需找是否有等于"hello"的字符串,有的话另a指向它,没有则在常量池中新建,然后a指向它。所以上例中,b直接指向这个常量,a和b在内存中是同一个对象,所以a==b为true。

而String newA = new String("hello")这种方方式,会在堆内存中新建一个字符串对象,所以与a、b所指向的常量池中对象是不同对象。==为false。

接下来出现了一个不太常用的intern方法。这个方法的作用是,在常量池中查找是否有与当前字符串值相同的常量,如果没有,则新建常量并返回常量引用,但当前引用不变;如果有直接返回引用。所以上例中newA.intern()返回了常量池中”hello“的引用与a、b为相同对象,但newA在intern后仍指向对中的那个对象,所以newA==newA.intern()不成立。这个方法对于重复率高的字符串可以提高内存利用率,减轻内存负担。但是常量表中的对象,一般不会被回收,会随着堆积占用越来越多的内存。所以要根据实际情况权衡利弊。

再往下,Java中罕见的运算符重载,是+和+=对String的重载,在使用中也有些需要注意的地方。类似"a" + "b"这样字符串常量用+连接的情形,在编译期间,JVM就将+连接优化为连接后的值。同时fianl修饰的已赋值String变量,在编译期同样被一个常量,保存到常量池中。所以上面输出中的14/17行的结果就不足为奇了。

在15行的结果中,JVM对于变量间的+操作,是转换为StringBuilder的append操作,所以产生了新的堆内对象。所以为false。

第18行的结果,你能给出原因么?

5159360.html

d64b7be1cbb9251e749f0b763a0632c8.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值