Java 数据类型之字符串
2006-05-12 15:30
323 查看
Java在字符串的处理方面和C#基本一致,但是仍旧存在细微差别。
在C#中,比较两个字符串可以使用==号,因为在C#中,比较两个字符串的时候,编译器会重载字符串比较方法,比如下面的代码:
public static void Test()
{
string str1 = "strings";
string str2 = "strings";
bool isEqual = str1 == str2;
Console.WriteLine(isEqual);
}
输出的结果为:True
当我们查看IL代码的时候,内部的操作就比较清楚了:
.method public hidebysig static void Test() cil managed
{
// 代码大小 27 (0x1b)
.maxstack 2
.locals init ([0] string str1,
[1] string str2,
[2] bool isEqual)
IL_0000: ldstr "strings"
IL_0005: stloc.0
IL_0006: ldstr "strings"
IL_000b: stloc.1
IL_000c: ldloc.0
IL_000d: ldloc.1
IL_000e: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: call void [mscorlib]System.Console::WriteLine(bool)
IL_001a: ret
} // end of method Class1::Test
上面的 IL_000e 行反映了编译器在比较两个字符串时的操作,即调用了System.String类中的一个方法op_Equality(string, string)对两个字符串进行比较。
当我们深入op_Equality(string, string)方法体内的时候,我们就很清楚的知道C#比较两个字符串多的算法:
00000000 push edi
00000001 push esi
00000002 push ebx
00000003 mov edi,ecx
00000005 mov esi,edx
00000007 cmp edi,esi
00000009 jne 00000014
0000000b mov eax,1
00000010 pop ebx
00000011 pop esi
00000012 pop edi
00000013 ret
00000014 test edi,edi
00000016 je 0000001C
00000018 test esi,esi
0000001a jne 00000022
0000001c xor eax,eax
0000001e pop ebx
0000001f pop esi
00000020 pop edi
00000021 ret
00000022 mov edx,esi
00000024 mov ecx,edi
00000026 cmp dword ptr [ecx],ecx
00000028 call dword ptr ds:[79C126F4h]
0000002e movzx ebx,al
00000031 mov eax,ebx
00000033 pop ebx
00000034 pop esi
00000035 pop edi
00000036 ret
由上面的汇编代码可以看出,C#首先会比较两个字符串的地址是否相等:
00000007 cmp edi,esi
如果相等则直接返回True (即 1),否则将进行逐字对比,然后返回对比结果。上面的代码用C语言表述为:
int Equality(char*str1, char *str2)
{
if (str1 == str2) return 1;
if (str1 == null || str2 == null) return 0;
CompareString(str1, str2); // 逐个字母比较两个字符串
}
然而在Java中,通过==来判断两个字符串的做法可能会存在风险。下面的代码为Java中的比较两个字符串的代码:
class StringSample
{
public static void main(String[] args)
{
String str1 = new String("strings");
String str2 = new String("strings");
System.out.println(str1 == str2);
}
}
输出的结果为:false
为了避免这样的错误,如果我们的目的明确为了比较两个字符串是否相等,则可以通过调用equals()方法来对两个字符串对象进行比较:
System.out.println(str1.equals(str2));
输出结果:true
小结:
C#与Java在比较字符串多的时候,各自采用了不同的比较方式,在C#中,两个字符串的比较是通过调用字符串比较方法进行逐字比较,而Java中则是通过判断引用来确定两个字符串是否相等,所以当Java中的字符串对象比较时,比并不是去比较字符串对象内的字符串是否相等,而是比较两个字符串对象的引用是否相等(即是否同时指向同一个字符串空间地址)。
在C#中,比较两个字符串可以使用==号,因为在C#中,比较两个字符串的时候,编译器会重载字符串比较方法,比如下面的代码:
public static void Test()
{
string str1 = "strings";
string str2 = "strings";
bool isEqual = str1 == str2;
Console.WriteLine(isEqual);
}
输出的结果为:True
当我们查看IL代码的时候,内部的操作就比较清楚了:
.method public hidebysig static void Test() cil managed
{
// 代码大小 27 (0x1b)
.maxstack 2
.locals init ([0] string str1,
[1] string str2,
[2] bool isEqual)
IL_0000: ldstr "strings"
IL_0005: stloc.0
IL_0006: ldstr "strings"
IL_000b: stloc.1
IL_000c: ldloc.0
IL_000d: ldloc.1
IL_000e: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: call void [mscorlib]System.Console::WriteLine(bool)
IL_001a: ret
} // end of method Class1::Test
上面的 IL_000e 行反映了编译器在比较两个字符串时的操作,即调用了System.String类中的一个方法op_Equality(string, string)对两个字符串进行比较。
当我们深入op_Equality(string, string)方法体内的时候,我们就很清楚的知道C#比较两个字符串多的算法:
00000000 push edi
00000001 push esi
00000002 push ebx
00000003 mov edi,ecx
00000005 mov esi,edx
00000007 cmp edi,esi
00000009 jne 00000014
0000000b mov eax,1
00000010 pop ebx
00000011 pop esi
00000012 pop edi
00000013 ret
00000014 test edi,edi
00000016 je 0000001C
00000018 test esi,esi
0000001a jne 00000022
0000001c xor eax,eax
0000001e pop ebx
0000001f pop esi
00000020 pop edi
00000021 ret
00000022 mov edx,esi
00000024 mov ecx,edi
00000026 cmp dword ptr [ecx],ecx
00000028 call dword ptr ds:[79C126F4h]
0000002e movzx ebx,al
00000031 mov eax,ebx
00000033 pop ebx
00000034 pop esi
00000035 pop edi
00000036 ret
由上面的汇编代码可以看出,C#首先会比较两个字符串的地址是否相等:
00000007 cmp edi,esi
如果相等则直接返回True (即 1),否则将进行逐字对比,然后返回对比结果。上面的代码用C语言表述为:
int Equality(char*str1, char *str2)
{
if (str1 == str2) return 1;
if (str1 == null || str2 == null) return 0;
CompareString(str1, str2); // 逐个字母比较两个字符串
}
然而在Java中,通过==来判断两个字符串的做法可能会存在风险。下面的代码为Java中的比较两个字符串的代码:
class StringSample
{
public static void main(String[] args)
{
String str1 = new String("strings");
String str2 = new String("strings");
System.out.println(str1 == str2);
}
}
输出的结果为:false
为了避免这样的错误,如果我们的目的明确为了比较两个字符串是否相等,则可以通过调用equals()方法来对两个字符串对象进行比较:
System.out.println(str1.equals(str2));
输出结果:true
小结:
C#与Java在比较字符串多的时候,各自采用了不同的比较方式,在C#中,两个字符串的比较是通过调用字符串比较方法进行逐字比较,而Java中则是通过判断引用来确定两个字符串是否相等,所以当Java中的字符串对象比较时,比并不是去比较字符串对象内的字符串是否相等,而是比较两个字符串对象的引用是否相等(即是否同时指向同一个字符串空间地址)。
相关文章推荐
- 黑马程序--JAVA字符串String、StringBuffer、StringBuilder、基本数据类型包装
- JAVA八种基本数据类型存储数值,字符和布尔值
- 怎样在Java中实现基本数据类型与字符之间的转换
- Java的char数据类型存储一个中文字符
- Java 数据类型转换之字符串
- [bxd学习java基本点]1.基本数据类型与字符串型转换与其他类型转成字符串
- JAVA字符数据类型及运算
- Java字节流和字符流的区别 (方法区别 操作基本单元区别 操作方式区别 处理数据类型区别) 之个人总结
- bit/byte/英文字符/汉字之间的换算及java八大基本数据类型的占字节数
- Java字符数据类型
- 【java基础】在Java中实现基本数据类型与字符、字符串之间的转换
- Java数据类型
- Java基本数据类型和运算符
- Java 数据类型
- Delphi中string数据类型的特殊用法(获取string字符串的单个字符)
- Java学习笔记----打印基本数据类型范围
- java数据类型
- Java数据类型和运算符
- java(优化24) Redis主要的五种数据类型使用
- java 8种基本数据类型