有 Java 编程相关的问题?

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

字符串在Java中使用toString后,为什么十六进制表示不能正确打印为‰?

在执行XOR并从十六进制转换为字符串后,我希望十六进制值“89”显示为“‰”,但Eclipse显示的是“?”。调试时,字符实际上为空。为什么?

  1. 我将字符串“r”转换为hex=>;"72".
  2. 然后我将“72”与“FB”(ā)=>;"89".
  3. 然后,我使用以下函数将“89”转换为字符串:

    public static String HexToString(String hex){
      StringBuilder sb = new StringBuilder();
      StringBuilder temp = new StringBuilder();
    
      for( int i=0; i<hex.length()-1; i+=2 ){
    
          //grab the hex in pairs
          String output = hex.substring(i, (i + 2));
    
          //convert hex to decimal
          int decimal = Integer.parseInt(output, 16);
    
          //convert the decimal to character
          sb.append((char)decimal);
    
          temp.append(decimal);
      }
      System.out.println("Decimal : " + temp.toString());
    
      return sb.toString();
      }
    

将结果打印到控制台后,我看到“?”而不是“/”。怎么了

编辑: 下面是显示decimal值和(char)decimal调试值的屏幕截图。 (char)decimal


共 (1) 个答案

  1. # 1 楼答案

    首先,Java在内部是完全Unicode的(虽然不是Unicode的最新版本,但复杂的原因在这里并不重要)。89十六进制将是\u0089,这是一个扩展控制字符(带对齐的字符列表),就像它在字符集ISO-8859-1中一样;对于前256个字符,Unicode与ISO-8859-1完全相同。根据你的描述,我猜你是在Windows上,并且配置了使用CP1252 character set的东西,它将89个十六进制解释为,但是Unicode的转换是通过映射到等效字符来完成的(在打印到控制台的过程中),而不仅仅是清除字节;由于该C1控制字符在CP1252中没有等效字符,因此它最终将作为替换字符(本例中为问号)

    这个故事的寓意是字符是而不是字节,在这个领域工作时需要非常小心使用字符集。(或者你应该使用一个完全Unicode的系统,在这个系统中,这些问题基本上消失了,尽管这样做的代价是字符成为比以前复杂得多的实体。)