n'不是一个字符常量. java_java_深入学习Java编程中的字符串的进阶使用,JAVA虽然是在C++基础上发展而来 - phpStudy...

深入学习Java编程中的字符串的进阶使用

JAVA虽然是在C++基础上发展而来,但却对C++的许多缺陷有所改进,其中一个不得不提的就是字符串,我们知道,随着学习的深入,进入MFC时,当处理字符串或字符时,常会需要通过_T()宏将字符或字符串变成UNICODE型,否则,会在处理中出现BUG,而在JAVA中,字符char或存储在Character类中的字符,不是一个字节,而是2个字节,采用UNICODE,这是为了支持全世界上的所有字符。

字符的序列组成字符串,有两种类型的字符串:一种是创建以后不需要修改的,称为字符串常量,在JAVA中,用String类存储;

一种是创建以后需要对其进行修改的,称为字符串变量,在JAVA中,用StringBuffer类操作和管理。

StringBuffer类

1、创建StringBuffer类对象

StringBuffer类对象表示的是字符串变量(注意是"变量"),每一个StringBuffer类对象都是可以扩充和修改的字符串变量。以下是常用的StringBuffer类构造函数:

(1)public StringBuffer()

创建一个新的空的StringBuffer类的对象,其容量初值设置成16个字符(注意是16个字符)

(2)public StringBuffer(int length)

创建一个新的空的StringBuffer类的对象,其容量初值设置成length个字符

(3)public StringBuffer(String str)

创建一个新的StringBuffer类的对象,其内容为str的内容,容量设置成str长度再加16个字符 (注意:再加上16个字符)

2、StringBuffer类对象的常用方法

(1)StringBuffer类对象的扩充

StringBuffer类提供两组方法用来扩充StringBuffer对象所包含的字符,分别是:

1)public StringBuffer append

(Object  obj)

append方法用于扩充StringBuffer对象所包含的字符,该方法将指定的参数对象转化为字符串后,将其附加在原来的StringBuffer对象之后,并返回新的StringBuffer对象。附加的的参数对象可以是各种数据类型的,如int、char、String、double等。

2)public StringBuffer insert(

int插入位置offset,参数对象类型,参数对象名)

该方法将指定的参数对象转化为字符串后,将其插入在原来的StringBuffer对象中指定的位置,并返回新的StringBuffer对象。

(2)StringBuffer类对象的长度与容量

一个StringBuffer类对象的长度指的是它包含的字符个数;容量指的是被分配的字符空间的数量。

1)public int length()

该方法返回当前StringBuffer类对象包含的字符个数。

2)public int capacity()

该方法返回当前StringBuffer类对象分配的字符空间的数量。

(3)StringBuffer类对象的修改

public void setCharAt(intindex,charch)

该方法将当前StringBuffer对象中的index位置的字符替换为指定的字符ch。

(4)字符串的赋值和加法

字符串是在程序中要经常使用的数据类型,在Java编译系统中引入了字符串的赋值和加法操作。

(5)其它方法类似String类的方法

3、利用StringTokenizer类分解字符串

StringTokenizer类位于java.util包中, 在使用该类时在程序开始加上

importjava.util.StringTokenizer或

importjava.util.*

StringTokenizer类

对于StringTokenizer类,其主要作用是将字符串按照给定的分割符进行分割,其功能和String类的split方法类似

1、StringTokenizer类的构造函数

(1)StringTokenizer(Stringstr)

为给定的字符串str创建一个StringTokenizer对象,其分隔符默认设置为“\t\n\r\f”,亦即:空格、水平制表符tab、换行、回车、表格符

(2)StringTokenizer(String str,String delim)

为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,默认不包含分隔符

3)StringTokenizer(String str,String delim,boolean returnDelims)

为给定的字符串str创建一个StringTokenizer对象,其分隔符为指定的字符串delim,如果returnDelims为true,则创建的StringTokenizer对象中的每个字符串包含有分隔符,否则不包含分隔符

2、StringTokenizer类的常用方法

nIntcountTokens()

返回StringTokenizer对象中被分割后子字符串的个数

nBooleanhasMoreElements()

该方法的功能和hasMoreTokens()方法的功能一样

nBooleanhasMoreTokens()

检测StringTokenizer对象中是否包含分割好的子字符串,有则返回true,否则返回false

ObjectnextElement()

该方法具有nextToken()一样的功能,主要区别是它返回的不是String对象,而是一个Object对象

StringnextToken()

返回StringTokenizer对象中下一个分割好的子字符串

StringnextToken(String delim)

返回StringTokenizer对象中下一个分割好的子字符串,但是分隔符被重新设定为delim

n其实在有些编程语言中,比如C语言,其字符串就是由字符数组构成的,每个字符串的结尾用“\0”标志,但是在Java中却不是这样的。

n在Java中,字符串通常是作为String类的对象存在着,如:Strings=“I like Java!”,其中“Ilike Java!”就是一个对象。

所以说,Java中的字符串和字符数组是完全不相同的,和C语言中的字符串也是不一样的!

n为了方便字符串和字符数组的转换,在String类中提供了许多这样的构造函数和方法

n如构造函数String(char[] value)

n方法toCharArray()

方法valueOf(char[] data)

常量池

对于源程序中出现的字符串常量,当程序运行时,会统一保存到一个常量池中进行缓存。

对引用这些缓存在常量池中的字符串的变量进行比较,用==也会得到正确的结果。

但在运行时,对字符串的各种操作如+、substring等等,都是会产生新的字符串对象的。

但是强大的编译器会对字符串常量的拼接进行优化,诸如s3 = "hell" + "o"时,s3仍然会

指向常量池中的字符串。但对于变量的运算,总不能要求虚拟机执行诸如s1 + s2时还要

判断结果是否已在常量池中了吧。因此,要用equals而非==去判断两个字符串是否相等。

public static void main(String[] args) {

// String constants are put in constant pool.

String s1 = "hello";

String s2 = "hello";

String s3 = "hell" + "o";

System.out.println(s1 == s2);

System.out.println(s1 == s3);

// Operation like +,substring on string create new one.

String s4 = "hell";

String s5 = s4 + "o";

System.out.println(s1 == s5);

System.out.println(s1.equals(s5));

// substring has special handle on substring(0)

String s6 = s1.substring(0);

System.out.println(s1 == s6);

}

测试代码s1、s2、s3的字节码:

0:   ldc     #16; //String hello

2:   astore_1

3:   ldc     #16; //String hello

5:   astore_2

6:   ldc     #16; //String hello

8:   astore_3

测试代码s4、s5的字节码:

41:  ldc     #30; //String hell

43:  astore  4

45:  new     #32; //class java/lang/StringBuilder

48:  dup

49:  aload   4

51:  invokestatic    #34; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;

54:  invokespecial   #40; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V

57:  ldc               #43; //String o

59:  invokevirtual   #45; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

62:  invokevirtual   #49; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

注意一点是substring方法,substring(0,3)是得到从字符0到2的字符串。这样设计的原因

也许是这样容易计算子串的长度,3-0=3。同时substring对于特殊参数有特别的优化处理:

public String substring(int beginIndex, int endIndex) {

if (beginIndex < 0) {

throw new StringIndexOutOfBoundsException(beginIndex);

}

if (endIndex > count) {

throw new StringIndexOutOfBoundsException(endIndex);

}

if (beginIndex > endIndex) {

throw new StringIndexOutOfBoundsException(endIndex - beginIndex);

}

return ((beginIndex == 0) && (endIndex == count)) ? this :

new String(offset + beginIndex, endIndex - beginIndex, value);

}

由此看出,String对象背后并没有什么神奇之处,对字节码有了些了解可以更好的理解它。

其实常量池中还保存类及其方法的很多信息,如包名、类名、方法签名等等,有兴趣可以

深入研究。相关阅读:

win10声音忽大忽小怎么办?win10播放音乐忽高忽低的解决办法

Win10怎么设置宽带自动连接 win10开机自动连接宽带设置方法详解

MySQL性能优化的一些技巧帮助你的数据库

ASP.NET 固定标题列与栏位的具体实现

MySQL数据库InnoDB数据恢复工具的使用小结详解

mysql利用group_concat()合并多行数据到一行

Bootstrap在windows phone 8下不兼容的解决方法

jQuery Easyui学习之datagrid 动态添加、移除editor

Javascript仿PHP $_GET获取URL中的参数

正则表达式性能优化方法(高效正则表达式书写)

Win10预览版10565已知问题汇总

Mac怎么连接打印机?苹果电脑Mac打印机设置教程

在Linux系统下用parted命令管理GPT分区的教程

探讨Ajax中同步与异步之间的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值