打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
深入Java字符串
深入Java字符串
Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生。
一、从根本上认识java.lang.String类和String池
首先,我建议先看看String类的源码实现,这是从本质上认识String类的根本出发点。从中可以看到:
1、String类是final的,不可被继承。public final class String。
2、String类是的本质是字符数组char[], 并且其值不可改变。private final char value[];
然后打开String类的API文档,可以发现:
3、String类对象有个特殊的创建的方式,就是直接指定比如String x = "abc","abc"就表示一个字符串对象。而x是"abc"对象的地址,也叫做"abc"对象的引用。
4、String对象可以通过“+”串联。串联后会生成新的字符串。也可以通过concat()来串联,这个后面会讲述。
6、Java运行时会维护一个String Pool(String池),JavaDoc翻译很模糊“字符串缓冲区”。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。下面是个系统内存示意图:
5、创建字符串的方式很多,归纳起来有三类:
其一,使用new关键字创建字符串,比如String s1 = new String("abc");
其二,直接指定。比如String s2 = "abc";
其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";
二、String对象的创建
String对象的创建也很讲究,关键是要明白其原理。
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
三、认识trim()、intern()和concat()、“+”。
三、认识空格、空串、null
下面看个例子:
/**
* Created by IntelliJ IDEA.<br>
* <b>User</b>: leizhimin<br>
* <b>Date</b>: 2008-6-2 22:14:16<br>
* <b>Note</b>: Please add comment here!
*/

public class StringTest {
    public static void main(String args[]) {
        //在池中和堆中分别创建String对象"abc",s1指向堆中对象
        String s1 = new String("abc");
        //s2直接指向池中对象"abc"
        String s2 = "abc";
        //在堆中新创建"abc"对象,s3指向该对象
        String s3 = new String("abc");
        //在池中创建对象"ab" 和 "c",并且s4指向池中对象"abc"
        String s4 = "ab" + "c";
        //c指向池中对象"c"
        String c = "c";
        //在堆中创建新的对象"abc",并且s5指向该对象
        String s5 = "ab" + c;

        String s6 = "ab".concat("c");
        String s7 = "ab".concat(c);

        System.out.println("------------实串-----------");
        System.out.println(s1 == s2); //false
        System.out.println(s1 == s3); //false
        System.out.println(s2 == s3); //false
        System.out.println(s2 == s4); //true
        System.out.println(s2 == s5); //false
        System.out.println(s2 == s6); //false
        System.out.println(s2 == s7); //false

        String b1 = new String("");
        String b2 = "";
        String b3 = new String("");
        String b4 = "".intern();
        String b5 = "" + "";
        String b6 = "".concat("");
        String b7 = "  ".trim();
        String b8 = "  ";
        String b9 = "    ".trim();

        System.out.println("------------空串-----------");
        System.out.println(b1 == b2);  //false
        System.out.println(b1 == b3);  //false
        System.out.println(b2 == b3);  //false
        System.out.println(b2 == b4);  //true
        System.out.println(b2 == b5);  //true*
        System.out.println(b2 == b6);  //true*
        System.out.println(b2 == b7);  //false*
        System.out.println("-----a----");
        System.out.println(b2.equals(b7));  //true
        System.out.println(b7 == b8);  //false
        System.out.println(b7 == b9);  //false
        System.out.println(b7.equals(b9)); //true
        System.out.println(b9 == null);//false

        System.out.println("b8.trim():");
        for (byte b : b8.getBytes()) {
            System.out.print(">>>" + (int) b + " ");
        }
        System.out.println("\nb8.trim():");
        for (byte b : b8.trim().getBytes()) {
            System.out.print(">>>" + (int) b + " ");
        }
        System.out.println("\nb9.trim():");
        for (byte b : b9.trim().getBytes()) {
            System.out.print(">>>" + (int) b + " ");
        }
    }
}
四、String的常见用法
1、字符串重编码
这个问题说来比较简单,转码就一行搞定,不信你看看,但究竟为什么要转码,是个很深奥的问题,看例子:
import java.io.UnsupportedEncodingException;

/**
* 字符串转码测试
*
* @author leizhimin 2009-7-17 10:50:06
*/

public class TestEncoding {
        public static void main(String[] args) throws UnsupportedEncodingException {
                System.out.println("转码前,输出Java系统属性如下:");
                System.out.println("user.country:" + System.getProperty("user.country"));
                System.out.println("user.language:" + System.getProperty("user.language"));
                System.out.println("sun.jnu.encoding:" + System.getProperty("sun.jnu.encoding"));
                System.out.println("file.encoding:" + System.getProperty("file.encoding"));

                System.out.println("---------------");
                String s = "熔岩博客";
                String s1 = new String(s.getBytes(), "UTF-8");
                String s2 = new String(s.getBytes("UTF-8"), "UTF-8");
                String s3 = new String(s.getBytes("UTF-8"));
                String s4 = new String(s.getBytes("UTF-8"), "GBK");
                String s5 = new String(s.getBytes("GBK"));
                String s6 = new String(s.getBytes("GBK"), "GBK");
                System.out.println(s1);
                System.out.println(s2);
                System.out.println(s3);
                System.out.println(s4);
                System.out.println(s5);
                System.out.println(s6);
        }
}
输出结果:
转码前,输出Java系统属性如下:
user.country:CN
user.language:zh
sun.jnu.encoding:GBK
file.encoding:UTF-8
---------------
熔岩博客
熔岩博客
熔岩博客
鐔斿博鍗氬

熔岩博客

Process finished with exit code 0
得出一结论:
a、转一个码,又用该码来构建一个字符串,是绝对不会出现乱码的,----你相当于没转。
b、转码与否,与字符串本身编码有关,字符串本身的编码与谁有关?----文件编码,或者你的IDE设置的编码有关。
在此,我用的IDEA开发工具,默认是UTF-8编码,但操作系统使用的是GBK,但没有问题,我只要按照UTF-8来读取我的字符串就不会有乱码。但是文件已经是UTF-8了,你非要转为GBK,不乱才怪!那有什么办法呢?在Windows下,用记事本或者Editplus打开后另存为(并修改编码方式即可)。
至于已经要从UFT-8转换为GBK,这就要靠内码转换工具了,是个比较复杂的问题,如果有谁想研究可以告诉我,一块研究研究。
2、字符比较
不就是个匹配关系吗?String类的API有一些可以做比较,如果不行,可以寻求正则表达式来解决。
3、获取某个字符
获取一个字符序列toCharArray() ,然后就随便玩去吧,中文就乱了。
4、字符串的截取
substring()
5、字符串的替换与查找
6、开始结束判断
startsWith()/endWith()
7、字符串的排序比较
compareTo(String anotherString)
          按字典顺序比较两个字符串。
compareToIgnoreCase(String str)
          不考虑大小写,按字典顺序比较两个字符串。
8、字符串的equals()和hashCode()
已经实现了好了,直接调用,不用重写
9、字符串的类型转化
太多了,String.valueOf()系列很多。
类似的Long.parseLong(String s)
10、字符串的复制
11、大小写转换
13、正则匹配

本文出自 “熔 岩” 博客,转载请与作者联系!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
关于JAVA String长度的限制
字符串一样,但是equals为false?
java可供判断某字符串是什么编码的一行代码
在JSP中,使用get提交方式出现乱码时,为什么要使用new String(s.getBytes(“iso
签名-Md5加密
关于String对象在创建之后不能改动的理解
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服