Java常量字符串String理解 String理解
以前关于String的理解仅限于三点:
1、String 是final类,不可继承
2、String 类比较字符串相等时时不能用“ == ”,只能用 "equals"
3、String 类不可更改
String 使用非常方便,因此一般涉及字符串时都用该类进行字符串处理
至于String类的类在机制,则极少去探究。
直到读到下面这个例子。
{
public static String strX="hello";
}
class Y
{
public static String strY="hello";
}
class Z
{
public static String strZ="hell"+"o";
}
class Test
{
public static void main(String[] args)
{
System.out.println( X.strX==Y.strY);
System.out.println( X.strX==Z.strZ);
String s1="hel";
String s2="lo";
System.out.println( X.strX==(s1+s2));
System.out.println( X.strX==(s1+s2).intern());
}
}
按照我的理解,类X,类Y,类Z中的三个常量字符串属于不同的对象,用 == 操作符比较,那么结果必然是 false,输出应该为:
false
false
false
false
但实际上输出确是:
true
true
false
true
使我大惑不解。并因此找了许多资料来看(尤其是C++和Java比较编程,里面解释比较详细),终于逐渐明白了原因。
== 只有在两个比较对象指向同一对象时,其值才为true。X.strX==Y.strY 与 X.strX==Z.strZ 测试结果都为true,说明这三个常量指向的都是同一个对象。
在JAVA中,String 是字符串常量。由相同序列的字符组成的两个字符串属于同一对象,位于内存中的同一个位置。每个字符串常量只有一个 String 对象来表示。即使这个字符串常量出现在一个程序的不同位置甚至一个程序的不同程序包中。也就是说,X.strX 与 Y.strY 由于都是同一字符序列,因此 指向的肯定是同一对象。
Z.strZ 也是如此。"hell"+"o",两个常量字符串相加后,创建了一个新的字符串常量(这个工作是编译期间完成的),它与 X.strX ,Y.strY有相同的字符序列,因此指向同一对象 。
虽然一个常量表达式将两个字符串常量链接在一起的结果在编译器已完成,但是
String s1="hel";
String s2="lo";
String s3=s1+s2;
这段代码中,s3只能在运行期间创建。这三条语句所创建的"hello"字符串作为String对象存储在内存中的一个独立位置。
Java提供一个机制,通过String类定义的intern()方法把一个运行时创建的字符串加到字符串常量池(如果它还没有入池)。如果上面的三条代码改为:
String s1="hel";
String s2="lo";
String s3=(s1+s2).intern();
java将把 s1+s2 所返回的字符串对象中的字符序列与已经存储在字符串常量池中的字符串进行比较。如果找到一个匹配,intern()就返回这个字符串的引用。如果没有找到匹配,s1+s2 所返回的字符串将被加入到字符串常量池中,并返回这个字符串常量的引用。
这就解释了为社么X.strX==(s1+s2)返回false,而X.strX==(s1+s2).intern()返回true。(s1+s2).intern()指向strX,strY,StrX指向的字符串常量"hello"。
本人追加测试代码如下:
/**
*
* @author ocq
*/
public class testString{
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2;
String s5 = "a" + "b";
String s6 = s1 + "b";
StringBuffer s7 = new StringBuffer("abc");
String s8 = s7.substring(3);
StringBuffer s9 = new StringBuffer("abc");
System.out.println((s3 == s4));//false
System.out.println(s3 == s5);//true
System.out.println(s3 == s6);//false
System.out.println(s4 == s6);//false
System.out.println((s4 == s8));//false
System.out.println((s7.toString() == s9.toString()));//false
}
}
原文:http://blog.csdn.net/kofsky/article/details/1882626
Java常量字符串String理解 String理解的更多相关文章
- Java常量字符串String理解
Java常量字符串String理解 以前关于String的理解仅限于三点:1.String 是final类,不可继承2.String 类比较字符串相等时时不能用“ == ”,只能用 "eq ...
- java常量,变量,静态变量的理解
最近考试出了一个很简单的题,看看他们对java常量,变量,静态变量的理解,代码如下: public class TestVar { /** * JAVA基础,常量,变量,静态变量 */ public ...
- Java基础-字符串连接运算符String link operator
Java基础-字符串连接运算符String link operator 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 字符串链接运算符是通过“+”进行拼接的. 一.使用“+”进行字 ...
- IntelliJ IDEA Error:(24, 35) java: 常量字符串过长
在转换一个JSON转Java对象是 idea 编译不通过 提示:Error:(24, 35) java: 常量字符串过长 File -> Settings -> Build,Execut ...
- IDEA报错 Error:(24, 35) java: 常量字符串过长
修改设置
- Java常量定义需要注意的两点
在任何开发语言中,都需要定义常量.在Java开发语言平台中也不例外.不过在Java常量定义的时候,跟其他语言有所不同.其有自己的特色.在这篇文章中,主要针对Java语言中定义常量的注意事项进行解析,帮 ...
- Java 之字符串(7)
什么是 Java 中的字符串 在程序开发中字符串无处不在,如用户登陆时输入的用户名.密码等使用的就是字符串.其实,在前面的章节中我们就已经使用了字符串, 例如我们在控制台中输出的 "Hell ...
- Java的字符串操作
目录 Java的字符串操作 一.不同字符串操作的对比 1.1 C++中const修饰指针 const在星号的左边,是被指向的常量不可变 const在星号的右边,是指针的指向不可变 二. Java字符串 ...
- 从Java的字符串池、常量池理解String的intern()
前言 逛知乎遇到一个刚学Java就会接触的字符串比较问题: 通常,根据"==比较的是地址,equals比较的是值"介个定理就能得到结果.但是String有些特殊,通过new Str ...
随机推荐
- elk系列4之kibana图形化操作【转】
preface 我们都搭建了ELK系统,且日志也能够正常收集的时候,那么就配置下kibana.我们可以通过kibana配置柱状图,趋势图,统计图,圆饼图等等各类图.下面就拿配置统计图和柱状图为例,结合 ...
- java 1.8 新特性 stream
并发提升 java 中Stream类似于hadoop中的数据分析的思路,只不过hadoop大,用的是多台机算机的计算生态,而java stream使用的单台计算机中的多cpu分析一块数据的过程.通过 ...
- Machine Learning系列--归一化方法总结
一.数据的标准化(normalization)和归一化 数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间.在某些比较和评价的指标处理中经常会用到,去除数据的单位限 ...
- Freemaker如何遍历key为non-string类型的map?
(一) 前置知识 Freemaker默认配置下会使用SimpleHash去包装后台传递的hashmap,下段摘抄自官方reference 同样,当你传递进去一个hashmap实例时,会替换为一个sim ...
- 增加Android模拟器空间(Internal Storage)
转载 http://vase.iteye.com/blog/2114664 初学Android,发现模拟器上有不少限制,譬如标题中的存储限制,无论用ADT Manager如何设置,内部存储空间不会 ...
- [Spring Data JPA问题]Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException
JPQL如下: @Modifying(clearAutomatically = true) @Query("UPDATE SyncTestFromTKDO SET stuAns = '' w ...
- cocos2dx 开发配置的一些环境变量(mac/linux)
通常开发需要配置一些环境变量,下面把我电脑的部分配置分析一下. 1.android开发配置,ndk,sdk,ant 2.cocos2dx开发配置,cocos2d-x export COCOS2DX_R ...
- Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) G - Xor-matic Number of the Graph 线性基好题
G - Xor-matic Number of the Graph 上一道题的加强版本,对于每个联通块需要按位算贡献. #include<bits/stdc++.h> #define LL ...
- bzoj 1877 最小费用流
思路:挺裸的费用流,拆拆点就好啦. #include<bits/stdc++.h> #define LL long long #define fi first #define se sec ...
- bzoj 1113
思路:对于两张高度一样的海报 i, j, 即 y[ i ] = y[ j ], 如果对于任意i < k < j 有y[ k ] > y[ i ] && y[ k ] ...