String 池(pool) 是一个特殊的内存区域,它有别于传统能够存储字符串常量的栈(heap)区。在应用程序的生命周期内,这些对象应用string变量。在Java中,String能够使用多种方式被创建。
1. String赋值
String str = "abc";
以上片段代码,JVM回去核实是否已经存在"abc"(与字符序列相同)。如果这样的字符串存在,JVM简单地将存在的对象赋值给这个变量str。否则,一个新的对象“abc”将被创建,并且它的应用将被赋值给变量str。
2. 使用new关键字
String str = new String("abc");
String s1 = "hello";
String s2 = "hello"; //store in a string pool.
String s3 = new String("hello");
System.out.println(s1==s2); //true, share the same memmory address
System.out.println(s1==s3); //false
这个版本以在内存创建了两个对象而结束。一个对象“abc”存在于string池中,另外一个在栈内存中引用一个变量str,并且有相同的字符序列“abc”。
看一个简单的例子:
String s1 = "hello";
String s2 = "hello"; //store in a string pool.
String s3 = new String("hello");
System.out.println(s1==s2); //true, share the same memmory address
System.out.println(s1==s3); //false
想想这个例子,你可能会得到答案。正如Java官方文档中说的,除非一个具体原生态的对象复制是必须的,使用构造器(constructor)是没有必要的,因为String是不可改变的。
下面看看string内的另外一个容易忽略的问题。原生的value数组[]是不可改变的。如果你用10000个字符创建一个string,并且使用5-100个字符创建100个子字符(substring),所有101个对象将有相同的10000字符大小。毫无疑问,它带来大的内存消耗。
看下面的程序:
public class TestSubstring {
public void testSubstring() throws NoSuchFieldException, IllegalAccessException {
//Our main String
String mainString = "i_love_java";
//Substring holds value 'java'
String subString = mainString.substring(7);
System.out.println(mainString);
System.out.println(subString);
//Lets see what's inside mainString
Field innerCharArray = String.class.getDeclaredField("value");
innerCharArray.setAccessible(true);
char[] chars = (char[]) innerCharArray.get(mainString);
System.out.println(Arrays.toString(chars));
//Now peek inside subString
chars = (char[]) innerCharArray.get(subString);
System.out.println(Arrays.toString(chars));
}
public static void main(String args[]){
try {
new TestSubstring().testSubstring();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
输出结果:
i_love_java
java
[i, _, l, o, v, e, _, j, a, v, a]
[i, _, l, o, v, e, _, j, a, v, a]
分享到:
相关推荐
深入理解JavaString#intern()内存模型Java开发Java经验技巧共4页.pdf.zip
深入理解 Java String#intern() 内存模型.docx
深入了解java 中的String 1、String类是final的,不可被继承。public final class String。 2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[]; 然后打开String类的API文档,...
Java中的String池
Java字符串池(String Pool)深度解析.docx
小心String的陷阱——深入剖析Java中String的处理机制
5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5.javaString类.zip5....
java String 使用详解,看完对String 的用法完全掌握
作者以易于理解的方式深入揭示了java虚拟机的内部工作原理,深入理解这些内容,将对读者更快速地编写更高效的程序大有裨益! 本书共分20章,第1-4章解释了java虚拟机的体系结构,包括java栈、堆、方法区、执行...
java中String类型转换方法.pdf
java基础String类选择题练习题,文档包含了答案与分析,适合学习用,本文档仅仅用于学习分享,不得用于商业用途
java编程中对字符串的各种方式的处理,包括(空字符串处理、判断是否是空字符串 null和"" 都返回 true、 把string array or list用给定的符号symbol连接成一个字符串、 判定第一个字符串是否等于的第二个字符串中的某...
在JDK1.5中,String类增加了一个非常有用的静态函数format(String format, Objece... argues),可以将各类数据格式化为字符串并输出。其中format参数指定了输出的格式,是最复杂也是最难掌握的一点,而argues则是一...
Java String与Byte类型转换;用到网络编程.
java字符串转String数组简单实例,简单但很实用
java String 编写的数据结构,一些基本的函数应用,适合初学者
java String 与各种进制字符之间的转换
【Java面试题】对String常量池的理解
Java 之 String 类型Java 之 String 类型
Java String对象的经典问题,有关String类的介绍