说说String这个类

public class Foo {
    public static void main(String[] args) {
        String strValue="ABCDEFG";
        strValue.substring(3);
        strValue.concat("123");
        System.out.println("result=" + strValue);

        String value = new String ("ABCDEFG");
        System.out.println(strValue== value);

    }
}

以这段代码为引子来理解下String这个类。

“String是不可变类,一旦String对象被创建,包含在对象中的字符序列是不可变的,直到对象被销毁”

意思就是String一旦在内存中创建它的字符序列是不被改变的,这是他与StringBuilder最大的区别。

那么我们再看看另外一个问题:

String s = "Hello";s = s + " world!";
这两行代码执行后,原始的String对象中的内容到底变了没有?

根据上面的原理我们可以知道:

没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 “Hello”,然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为”Hello world!”,原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。

同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:

public class Demo {

private String s;

public Demo {

s = “Initial Value”;

}

}

而非

s = new String(“Initial Value”);

后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

上面的结论还基于这样一个事实:

对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。

有了这样一个结论,对上面的那个代码的输出情况就迎刃而解。

那么我再贴一段代码,看看大家对String的理解:

、下面这条语句一共创建了多少个对象:String s="a"+"b"+"c"+"d";

答:对于如下代码:

String s1 = “a”;

String s2 = s1 + “b”;

String s3 = “a” + “b”;

System.out.println(s2 == “ab”);

System.out.println(s3 == “ab”);

第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。

题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,

String s = “a” + “b” + “c” + “d”;

System.out.println(s == “abcd”);

最终打印的结果应该为true。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-10 08:32:44

说说String这个类的相关文章

String分割类

StringTokenizer类 用的时候要 import java.util.StringTokenizer; StringTokenizer b=new StringTokenizer( Stringa," , . 分裂符号) b.countTokens()  有多少个数 b.hasMoreTokens()  还有吗 b.nextToken() 显示出来啊 使用Scanner类 在字符串中解析需要的数据 String a="saf 23132 adf 231 asdf 13 ad&

java基础知识回顾之---java String final类之intern方法

public class StringObjectDemo { /** * @param args */ public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " ");//true System.out.print((Other.hello == hel

java基础知识回顾之---java String final类普通方法的应用之“按照字节截取字符串”

/*需求:在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符.但对应的字节数不同,一个汉字占两个字节.定义一个方法,按照最大的字节数来取子串.如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃.如果去四个字节就是“ab你”,取五个字节还是“ab你”.*/ 代码:其实是一个解码和编码的问题,要明白UTF-8码表和GBK码表的区别,UTF-8中用三个字节代表一个汉字,GBK使用2个字节代表一个汉字. 且在码表中都是用数字存放这些汉字.

java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析

/** *   栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放  在常量池中). 堆(heap):存放所有new出来的对象. *   静态存储:存放静态成员(static定义的). 常量池(constant pool):在堆中分配出来的一块存储区域,存放储显式的String常量和基本类型常量(float.int等).另外,可以存储不经常改变的东西 *                       p

java基础知识回顾之---java String final类普通方法的应用之字符串数组排序

/* * 1,给定一个字符串数组.按照字典顺序进行从小到大的排序. * {"nba","abc","cba","zz","qq","haha"} *  * 思路: * 1,对数组排序.可以用选择,冒泡都行. * 2,for嵌套和比较以及换位. * 3,问题:以前排的是整数,比较用的比较运算符,可是现在是字符串对象. *   字符串对象怎么比较呢?爽了,对象中提供了用于字符串对象比较的功能

【工作总结】C++ string工具类

工作中在不同的项目中经常对字符串一些特殊处理,比如分隔.比如转码.比如去空格等等,这里整理了一下最近使用的一些字符串操作方法,有些也是从网上搜来的代码,来源已无从查起,所以就不贴来源了. 头文件 1 /********************************************* 2 *Copyright(C) zhiqli 3 *FileName: StrUtils.h 4 *Author: zhiqli 5 *Version: v1.0 6 *Date: 2014-8-6 7 *

java基础知识回顾之---java String final类普通方法的应用之“模拟字符串Trim方法”

/* * 4,模拟一个trim功能一致的方法.去除字符串两端的空白  * 思路: * 1,定义两个变量. * 一个变量作为从头开始判断字符串空格的角标.不断++. * 一个变量作为从尾开始判断字符串空格的角标.不断--. * 2,判断到不是空格为止,取头尾之间的字符串即可. *  *  使用char charAt(int index);方法根据index索引,取出字符串 *  使用String substring(int beginIndex, int endIndex)//包含begin 不包

java基础知识回顾之---java String final类普通方法的应用之“两个字符串中最大相同的子串”

/* * 3,两个字符串中最大相同的子串. * "qwerabcdtyuiop" * "xcabcdvbn" *  * 思路: * 1,既然取得是最大子串,先看短的那个字符串是否在长的那个字符串中. *   如果存在,短的那个字符串就是最大子串. * 2,如果不是呢,那么就将短的那个子串进行长度递减的方式取子串,去长串中判断是否存在. *   如果存在就已找到,就不用在找了. * 3.先找最大的子串,再递减子串找,找到,就停止 */ 原理图如图: 代码: publi

java基础知识回顾之---java String final类普通方法的应用之“子串在整串中出现的次数”

/* * 2 一个子串在整串中出现的次数. * "loveerlovetyloveuiloveoplove" * 思路: * 1,要找的子串是否存在,如果存在获取其出现的位置.这个可以使用indexOf完成. * 2,如果找到了,那么就记录出现的位置并在剩余的字符串中继续查找该子串, * 而剩余字符串的起始位是出现位置+子串的长度. * 3,以此类推,通过循环完成查找,如果找不到就是-1,并对 每次找到用计数器记录.  * 使用 indexOf()获取某个字符子串在整串中的位置,还使用