有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么这两个字符串不相等?

我通过UDP发送一个数据包,由于某种原因,我无法比较从数据包中提取的字符串和我创建的字符串,即使打印时它们的值相同(没有尾随空格)

byte[] incoming = new byte[1000];
DatagramPacket request = new DatagramPacket(incoming, incoming.length);
serverSocket.receive(request);
String str = new String(request.getData());
String str2 = new String("message received");

if(str.equals(str2))
{
   System.out.println("equal");
}

有什么原因吗


共 (1) 个答案

  1. # 1 楼答案

    这是因为new String(request.getData())没有返回"message received"

    问题[可能]是因为new String(byte[])试图使用默认编码中提供的所有(1000个)字节,其结尾是一堆NUL('\0')字符,这些字符附加到实际字符串内容中,使其不等于。这样的字符在调试器中很容易看到,尽管这样的NUL字符在作为正常文本显示时经常“丢失”,如println

    很简单:"hello".equals("hello\0")是假的

    几种解决方案包括:

    1. Frame字符串,比如用组成字符串的字节数作为发送数据的前缀,然后使用a String constructor that takes a limit/length

    2. 通过指定解码或删除的限制,防止处理任何尾随的0

    3. 解码数据后删除所有NUL字符

    由于选项#3很容易1(直到可以固定使用#1/#2),请考虑:

    String str = new String(request.getData(), "UTF-8"); // Specify an encoding!
    int nul = str.indexOf('\0');
    if (nul > -1) {
       str = str.substring(0, nul);
    }
    

    1虽然修剪是最简单的,但它通常并不合适。#3大于#2的最大问题是它首先解码所有字节,然后过滤字符。在不同的编码下(尽管ASCII和UTF-8应该是“安全的”),这可能会导致实际字符串内容之后出现非NUL垃圾,具体取决于缓冲区中存在的内容

    另外,手动指定编码为new String(byte[] ..)String.getBytes(..)。否则将使用“默认编码”,如果不同的系统使用不同的默认编码,可能会导致问题