`
woshixushigang
  • 浏览: 562374 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

string

 
阅读更多

String a = "ab"; 
String b = "a" + "b"; 
System.out.println((a == b)); 

打印结果会是什么?类似这样的问题,有人考过我,我也拿来考过别人(蛮好玩的,大家也可以拿来问人玩),一般答案会是以下几种: 

1.true 
    "a" + "b" 的结果就是"ab",这样a,b都是"ab"了,内容一样所以"相等",结果true 
    一般java新人如是答。 
2.false 
    "a" + "a"会生成新的对象"aa",但是这个对象和String a = "ab";不同,(a == b)是比较对象引用,因此不相等,结果false 
    对java的String有一定了解的通常这样回答。 
3.true 
    String a = "ab";创建了新的对象"ab"; 再执行String b = "a" + "b";结果b="ab",这里没有创建新的对象,而是从JVM字符串常量池中获取之前已经存在的"ab"对象。因此a,b具有对同一个string对象的引用,两个引用相等,结果true. 
    能回答出这个答案的,基本已经是高手了,对java中的string机制比较了解。 
    很遗憾,这个答案,是不够准确的。或者说,根本没有运行时计算b = "a" + "b";这个操作.实际上运行时只有String b = "ab"; 
    3的观点适合解释以下情况: 
    String a = "ab"; 
    String b = "ab"; 
    System.out.println((a == b)); 
    如果String b = "a" + "b";是在运行期执行,则3的观点是无法解释的。运行期的两个string相加,会产生新的对象的。(本文后面对此有解释) 

4.true 
    下面是我的回答:编译优化+ 3的处理方式 = 最后的true 
    String b = "a" + "b";编译器将这个"a" + "b"作为常量表达式,在编译时进行优化,直接取结果"ab",这样这个问题退化 
    String a = "ab"; 
    String b = "ab"; 
    System.out.println((a == b)); 
    然后根据3的解释,得到结果true 

    这里有一个疑问就是String不是基本类型,像 
int secondsOfDay = 24 * 60 * 60; 
    这样的表达式是常量表达式,编译器在编译时直接计算容易理解,而"a" + "b" 这样的表达式,string是对象不是基本类型,编译器会把它当成常量表达式来优化吗? 
    下面简单证明我的推断,首先编译这个类: 
public class Test { 
    private String a = "aa"; 
       复制class文件备用,然后修改为 
public class Test { 
    private String a = "a" + "a"; 
    再次编译,用ue之类的文本编辑器打开,察看二进制内容,可以发现,两个class文件完全一致,连一个字节都不差. 
    ok,真相大白了.根本不存在运行期的处理String b = "a" + "b";这样的代码的问题,编译时就直接优化掉了。 


下面进一步探讨,什么样的string + 表达式会被编译器当成常量表达式? 
String b = "a" + "b"; 
这个String + String被正式是ok的,那么string + 基本类型呢? 

String a = "a1"; 
String b = "a" + 1;
System.out.println((a == b));  //result = true 

String a = "atrue"; 
String b = "a" + true; 
System.out.println((a == b));  //result = true 

String a = "a3.4"; 
String b = "a" + 3.4; 
System.out.println((a == b));  //result = true 
   
可见编译器对string + 基本类型是当成常量表达式直接求值来优化的。 

再注意看这里的string都是"**"这样的,我们换成变量来试试: 
String a = "ab"; 
String bb = "b"; 
String b = "a" + bb; 
System.out.println((a == b));   //result = false 
这个好理解,"a" + bb中的bb是变量,不能进行优化。这里很很好的解释了为什么3的观点不正确,如果String+String的操作是在运行时进行的,则会产生新的对象,而不是直接从jvm的string池中获取。 

再修改一下,把bb作为常量变量: 
String a = "ab"; 
final String bb = "b"; 
String b = "a" + bb; 
System.out.println((a == b));   //result = true 
竟然又是true,编译器的优化好厉害啊,呵呵,考虑下面这种情况: 
String a = "ab"; 
final String bb = getBB(); 
String b = "a" + bb; 
System.out.println((a == b));    //result = false 
private static String getBB() { 
return "b"; 
看来java(包括编译器和jvm)对string的优化,真的是到了极点了,string这个所谓的"对象",完全不可以看成一般的对象,java对string的处理近乎于基本类型,最大限度的优化了几乎能优化的地方。 

另外感叹一下,string的+号处理,算是java语言里面唯一的一个"运算符重载"(接触过c++的人对这个不会陌生)吧?
分享到:
评论

相关推荐

    StringAPI.java

    Java String 类型 API 测试代码 1.String和char[]之间的转换 toCharArray(); 2.String和byte[]之间的转换 getBytes() Arrays工具类 : Arrays.toString(names) String类 String replace(char oldChar, ...

    public static String[] split(String s, String regex)

    public static String[] split(String s, String regex) s参数为待拆分字符串, regex参数有两种格式: 单字符的字符串(长度1),功能如下:split(“ab#12#453”, “#”) 返回带5个元素的数组:ab, #, 12, #, 453 ...

    《C++String深入详解2.0版》PDF

    一、 C++的string的使用 3 1.1 C++ string简介 3 1.2 string的成员 3 1.2.1 append 3 1.2.2 assign 4 1.2.3 at 4 1.2.4 begin 5 1.2.5 c_str 5 1.2.6 capacity 5 1.2.7 clear 6 1.2.8 compare 6 1.2.9 copy 6 1.2.10...

    基于Keil实现字符串函数string.h的简单应用

    基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用...

    String a="hello" String b="hello" a==b 返回true的问题分析

    String a="hello world"; //在java中有一个常量池,当创建String 类型的引用变量给它赋值时,java会到它的常量池中找"hello world"是不是在常量池中已存在。如果已经存在则返回这个常量池中的"hello world"的地址...

    详解C++ string常用截取字符串方法

    string常用截取字符串方法有很多,但是配合使用以下两种,基本都能满足要求: find(string strSub, npos); find_last_of(string strSub, npos); 其中strSub是需要寻找的子字符串,npos为查找起始位置。找到返回子...

    StringUtil.java

    java编程中对字符串的各种方式的处理,包括(空字符串处理、判断是否是空字符串 null和"" 都返回 true、 把string array or list用给定的符号symbol连接成一个字符串、 判定第一个字符串是否等于的第二个字符串中的某...

    305-字符串函数string.h应用举例(51单片机C语言实例Proteus仿真和代码)

    305-字符串函数string.h应用举例(51单片机C语言实例Proteus仿真和代码)305-字符串函数string.h应用举例(51单片机C语言实例Proteus仿真和代码)305-字符串函数string.h应用举例(51单片机C语言实例Proteus仿真和代码)...

    C语言头文件 STRING.H

    C语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING.HC语言头文件 STRING....

    C#_string_byte数组转换解析

    C# string byte数组转换解析 C# string byte数组转换实现的过程是什么呢?C# string byte数组间的转换需要注意什么呢?C# string byte数组间转换所涉及的方法是什么呢?让我们来看看具体的内容: C# string byte数组...

    c++作业设计string类

    设计string类 要求: 1、为该类定义构造函数,析构函数和赋值操作。构造函数至少应有三个:无参构造函数、C风格字符串构造函数和复制构造函数 2、为string类提供必要的成员函数,可以参考C++类库的string类提供了...

    C# char[]与string byte[]与string之间的转换详解

    1、char[]与string之间的转换 //string 转换成 Char[] string str=hello; char[] arr=str.ToCharArray(); //Char[] 转换成 string string str1 = new string(arr); 2、byte[]与string之间的转化 string str = 你好...

    《深入学习c++string》2.1版

    一、 C++的string的使用 4 1.1 C++ string简介 4 1.2 string的成员 4 1.2.1 append 4 1.2.2 assign 5 1.2.3 at 5 1.2.4 begin 6 1.2.5 c_str 6 1.2.6 capacity 6 1.2.7 clear 7 1.2.8 compare 7 1.2.9 copy 7 1.2.10...

    c++ string转换double

    string转换double string转换double string转换double string转换double

    C-Lib-string.c

    Linux的作者Linus Torvalds的C语言函数库源代码(部分)string.c <br>1 /* 2 * linux/lib/string.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 */ 6 7 /* 8 * stupid library ...

    String和string区别以及string详解.doc

    String和string区别以及string详解

    protobuf根据DebugString输出字串反解pb对象的实例(C++)

    使用过protobuf的同学肯定对pb的DebugString相关方法再熟悉不过了,其作用就是打印输出pb对象。有些时候我们可能会有根据这个输出还原原始pb对象的需求。仔细观察发现输出并不是标准json格式,也就是说基于json→pb...

    String.h函数详解

    String.h函数详解 1、strcpy  函数名: stpcpy  功 能: 拷贝一个字符串到另一个  用 法: char *stpcpy(char *destin, char *source);  程序例:  #include <stdio.h>  #include <string.h>  int main...

    js中string和number类型互转换技巧(分享)

    1、string–>number string类型 *1 即可变成 number类型 2、number–>string number类型 +’‘ 即可变成 string 类型 [removed] function screenInfo() { var str = '012.8372'; var s = 0; str = str...

Global site tag (gtag.js) - Google Analytics