先看看下面的代码


    public String makinStrings()
    {
        String s = "Fred";
        s = s + "47";
        s = s.substring(2, 5);
        s = s.toUpperCase();
        return s.toString();
    }

问:调用makinStrings方法会创建几个String对象呢。  答案:3个

上面的方法有五条语句:现在让我们来一条一条分析一下。

String s = "Fred";   结论:创建了一个String对象

这条语句相当于String s = new String("Fred");
因此,毫无疑问,第一条语句创建了一个String对象,我想没有有疑问吧?

s = s + "47";   结论:未创建String对象

这条语句也许很多人认为是创建了String对象,我一开始也是这么认为的。但是为了验证我的想法。决定
用点法术恢复这条语句的本来面目。(有很多时候,编译器总是在里面搞一些小动作,javac.exe也不例外)

现在找到这个程序所生成的.class文件(假设是Test.class),找一个反编译工具,我推荐JAD,可以http://www.softpedia.com/progDownload/JAD-Download-85911.html下载
下载后,有一个jad.exe,将其路径放到环境变量path中(只限windows)。并在.class文件的当前路径执行如下的命令:

jad Test

然后大喊一声“还我本来面目”

会在当前目录下生成一个Test.jad文件,打开它,文件内容如下:

 
    public String makinStrings()
    {
        String s = "Fred";
        s = (new StringBuilder(String.valueOf(s))).append("47").toString();
        s = s.substring(2, 5);
        s = s.toUpperCase();
        return s.toString();
    }
 

哈哈,其他的语句都没变,只有第二条变长了,虽然多了个new,但是建立的是StringBuilder对象。原来
这是java编译器的优化处理。原则是能不建String对象就不建String对象。而是用StringBuilder对象
加这些字符串连接起来,相当于一个字符串队列。这种方式尤其被使用在循环中,大家可以看看下面的代码:
        String s = "";
        for(int i=0; i < 10000000; i++)
            s += "aa";
    没有哪位老大认为这是建立了10000000个String对象吧。但不幸的是,上面的代码虽然没有建立10000000个String对象
但却建立了10000000个StringBuilder对象,那是为什么呢,自已用jad工具分析一下吧。
正确的写法应该是:

StringBuilder sb = new StringBuilder("");
        for(int i=0; i < 10000000; i++)
            sb.append(String.valueOf(i));

s = s.substring(2, 5);     结论:创建了一个String对象
 也许有很多人一开始就认为这条语句是创建了一个String对象,那么恭喜你,这条语句确实创建了一个String对象
 实际上就是substring方法创建了一个String对象。这也没什么复杂的,自已下一个JDK源代码,看看substring是如何实现的
 就可以知道了。我先说一下吧。先不用管substring是如何实现的,反正在substring方法返回时使用了一个new显式地建立了一个String对象
 不信自己看看源码。
s = s.toUpperCase();   结论:创建了一个String对象

toUpperCase()和substring方法类似,在返回时也是使用了new建立了一个String对象。

return s.toString();   结论:未创建String对象

toString方法返回的就是this,因此,它的返回值就是s。

这道题还算比较简单,再给大家出一个更复杂一点的,也是关于String对象的创建的(只是改了一个原题)。

    public String makinStrings()
    {
        String s = "Fred";
        s = s + "Iloveyou.".substring(1).toLowerCase();
        s = s.substring(0);
        s = s.substring(0,1).toUpperCase();
        return s.toString();
    }

先公布答案吧,上述代码也创建了3个String对象,哈哈!

为什么呢?

要想知道为什么,先得弄清楚substring、toLowerCase和toUpperCase什么时候创建String对象,什么时候不创建对象。

substring方法在截取的子字符串长度等于原字符串时,直接返回原字符串。并不创建新的String对象。

toLowerCase方法在字符串中更本没有需要转换的大写字母时直接返回原字符串,如"abcd".toLowerCase()直接返回abcd,并不创建新的String对象

toUpperCase方法和toLowerCase类似。"ABCD".toUpperCase()直接返回ABCD。

知道了这个,上面的代码就非常清楚了。

    public String makinStrings()
    {
        String s = "Fred";     // 创建一个String对象
        s = s + "Iloveyou.".substring(1).toLowerCase();  // substring(1)创建一个String对象,由于toLowerCase()转换的字符串是"loveyou.",没有大写字母,因此,它不创建新的String对象
        s = s.substring(0);   // 由于substring(0)截获的是s本身,因此,这条语句不创建新的String对象
        s = s.substring(0,1).toUpperCase();  // substring(0,1)创建了一个String对象,但由于substring(0,1)的结果是"F",为一个大写字母,因此,toUpperCase直接返回"F"本身。
        return s.toString();
    }

关于Java String对象创建问题解惑相关推荐

  1. java string对象创建_String对象创建个数

    s = new String("xyz");创建了几个String Object?两个对象,一个是"xyx",一个是指向"xyx"的引用对象 ...

  2. java string对象创建_Java问题解析:到底创建了几个String对象

    // 如果d和c没有指向了同一个对象,则说明d没有被加入字符串池 else { System.out.println(""ab"+"cd" 创建的对象 ...

  3. java string对象放在什么区域_java中String对象的存储位置

    packagetest.string.equal;public classMain {/**创建了三个对象,"helloworld对象创建在常量池中",每次new String() ...

  4. java反射创建带参数对象_反射 Java反射对象创建 - 闪电教程JSRUN

    Java反射 -Java反射对象创建 我们可以使用反射动态创建类的对象.通过调用其中一个构造函数. 然后我们可以访问对象的细分的值,设置它们的值,并调用它们的方法. 有两种方法来创建对象: 使用no- ...

  5. java string 对象地址_Java中String对象的存储位置(学习笔记)

    packagetest.string.equal;public classMain {/*** 创建了三个对象,"helloworld对象创建在常量池中",每次new String ...

  6. java string对象创建对象_Java String 创建了几个对象

    我们首先来看一段代码: Java代码 String str=new String("abc"); 紧接着这段代码之后的往往是这个问题,那就是这行代码究竟创建了几个String对象呢 ...

  7. 5.java String对象

    String 类 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 实例化String类 实例化一个String类有两种方法: ...

  8. java 给对象创建实例_Java中创建(实例化)对象的五种方式

    Java中创建(实例化)对象的五种方式1.用new语句创建对象,这是最常见的创建对象的方法. 2.通过工厂方法返回对象,如:String str = String.valueOf(23); 3.运用反 ...

  9. java string对象名称_java中常见对象——String

    字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. A:字符串字面值"abc"也可以看成是一个字符串对象. B:字符串是常量,一旦被赋值,就不能被改变. 构造方法: ...

最新文章

  1. 基于结构光测量技术和3D物体识别技术开发的机器人3D视觉引导系统
  2. oracle安装问题: 11g安装未填写hosts导致弹窗错误
  3. python编程从入门到实践读书笔记-《Python编程:从入门到实践》项目部分读书笔记(二)...
  4. 红黑树(一)之 原理和算法详细介绍---转帖
  5. golang 开发 Struct 转换成 map 两种方式比较
  6. 用API获得Internet Explorer_Server类的HTML
  7. c++ const限定符
  8. datasnap 的HTTP 调用返回JSON
  9. C语言循环时无故释放变量吗,C语言 - while循环体内变量重新声明,陷入***循环。...
  10. 智能视屏会议系统(19)---开源视频会议SIP协议栈
  11. python模拟登录新浪微博自动获得调用新浪api所需的code
  12. linux远程拷贝快捷键远程,linux命令scp远程拷贝
  13. 电子专业 英语词汇大全(持续更新)
  14. Android应用签名
  15. WIN8转WIN7的两三事
  16. android画a4矩形,将Android视图转换为A4大小的PDF
  17. 国密算法分类及介绍(sm系列密码算法)
  18. js-入门(字符串-运算符) html常用命令代码行
  19. ICP许可证有多重要
  20. python正则去掉重复单词_python使用正则表达式去除中文文本多余空格,保留英文之间空格方法详解 | 学步园...

热门文章

  1. python全网表情包_Python爬虫爬取最右公众号表情包资源
  2. Spring MVC拦截器实现用户登录权限验证案例
  3. Python pow() 函数
  4. Selenium API-WebElement 属性
  5. ggplot2 | 使用小提琴图+箱形图+抖动图展示数据分布情况
  6. python中circle函数的用法,python画圆运用了什么函数
  7. php 白名单,php实现ip白名单黑名单功能
  8. 前端必须学会的5个原生JavaScript对象方法
  9. python处理子进程_Python多处理+子进程问题
  10. c html循环ienumerable,C#方法返回IEnumerable实现用foreach遍历