Java 为什么字节和字符串之间的转换过程中字节数据会发生变化?

Java 为什么字节和字符串之间的转换过程中字节数据会发生变化?,java,string,byte,Java,String,Byte,我发现了一个我在Java中无法真正理解的现象,我发布了一个问题 将一些数据放入字节数组 将字节数组转换为字符串 将转换后的字符串转换回字节数组 当比较第一个数据和转换后的数据时,其中一些数据的输出会有所不同 下面是源代码和日志 源代码 // 1. Input byte array data byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, (byte)3}; log.info("Bef

我发现了一个我在Java中无法真正理解的现象,我发布了一个问题

  • 将一些数据放入字节数组
  • 将字节数组转换为字符串
  • 将转换后的字符串转换回字节数组
  • 当比较第一个数据和转换后的数据时,其中一些数据的输出会有所不同
  • 下面是源代码和日志

    源代码

    // 1. Input byte array data
    byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, (byte)3};
    log.info("Before ByteTest");
    log.info("bytesLength : " + beforeBytes.length);
    for (int i = 0; i < beforeBytes.length; ++i)
    {
        log.info(i + " : " + (int)beforeBytes[i]);
    }
    
    // 2. Convert byte array to string
    String testString = new String(beforeBytes);
    
    // 3. Convert string to byte array
    byte[] afterBytes = testString.getBytes();
    log.info("After ByteTest");
    log.info("bytesLength : " + afterBytes.length);
    for (int i = 0; i < afterBytes.length; ++i)
    {
        log.info(i + " : " + (int)afterBytes[i]);
    }
    
    即使在转换之后,我也希望保留与现有数据相同的数据
    有解决办法吗?

    您应该使用如下编码器和解码器:

            // 2. Convert byte array to string
        String testString = Base64.getEncoder().encodeToString(beforeBytes);
    
        // 3. Convert string to byte array
        byte[] afterBytes = Base64.getDecoder().decode(testString);
    
        // 1. Input byte array data
        byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, 
        (byte)3};
        log.info("Before ByteTest");
        log.info("bytesLength : " + beforeBytes.length);
        for (int i = 0; i < beforeBytes.length; ++i)
        {
            log.info(i + " : " + (byte)beforeBytes[i]);
        }
    
        // 2. Convert byte array to string
        String testString = Base64.getEncoder().encodeToString(beforeBytes);
    
        // 3. Convert string to byte array
        byte[] afterBytes = Base64.getDecoder().decode(testString);
        log.info("After ByteTest");
        log.info("bytesLength : " + afterBytes.length);
        for (int i = 0; i < afterBytes.length; ++i)
        {
            log.info(i + " : " + (byte)afterBytes[i]);
        }
    
    最后,您的代码如下所示:

            // 2. Convert byte array to string
        String testString = Base64.getEncoder().encodeToString(beforeBytes);
    
        // 3. Convert string to byte array
        byte[] afterBytes = Base64.getDecoder().decode(testString);
    
        // 1. Input byte array data
        byte[] beforeBytes = new byte[]{(byte)-83, (byte)-95, (byte)-55, (byte)-49, 
        (byte)3};
        log.info("Before ByteTest");
        log.info("bytesLength : " + beforeBytes.length);
        for (int i = 0; i < beforeBytes.length; ++i)
        {
            log.info(i + " : " + (byte)beforeBytes[i]);
        }
    
        // 2. Convert byte array to string
        String testString = Base64.getEncoder().encodeToString(beforeBytes);
    
        // 3. Convert string to byte array
        byte[] afterBytes = Base64.getDecoder().decode(testString);
        log.info("After ByteTest");
        log.info("bytesLength : " + afterBytes.length);
        for (int i = 0; i < afterBytes.length; ++i)
        {
            log.info(i + " : " + (byte)afterBytes[i]);
        }
    
    //1。输入字节数组数据
    字节[]beforeBytes=新字节[]{(字节)-83,(字节)-95,(字节)-55,(字节)-49,
    (字节)3};
    日志信息(“BYTETETEST前”);
    log.info(“bytesLength:+beforeBytes.length”);
    for(int i=0;i
    您使用的.getBytes()方法不是最合适的,因为您没有在构造函数中编写字符集(例如UTF-8),构造函数可以添加或修改一些数据。使用Base64编码器和解码器更好。
    亲切问候。

    这是否回答了您的问题?这是一个很好的问题,很容易让人困惑。Java没有无符号字节(负数)。如果要保留负数,则可以使用另一种数据类型,如int数组
    int[]beforeInt=newint[]{-83,-95,-55,-49,3},或者您可以将它们转换回无符号字节,如下所示:63是
    ,当字节组合未映射到字符集中的有效字符时(并且字符集不是UTF-8,它将使用不同的字符作为替换字符),它将用作替换字符。因此,问题取决于实际的字符集(打印出
    System.getProperty(“file.encoding”)
    )。您应该始终明确指定字符集。但是,如果您的目标是将二进制数据存储在字符串中,那么这不是正确的方法(尽管您可以使用字符集iso-8859-1)。