Java 数据类型之字符串

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中的字符串对象比较时,比并不是去比较字符串对象内的字符串是否相等,而是比较两个字符串对象的引用是否相等(即是否同时指向同一个字符串空间地址)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值