Java getBytes()

Java getBytes(),java,Java,你知道我为什么不打招呼的问题吗 byte f [] ="hello".getBytes(); System.out.println(f.toString()); 因为byte[]#toString()通常不作为new String(byteArray)实现,这将导致您期望的结果(例如System.out.println(new String(byteArray)); 您可能想看一看…因为字节数组的toString方法根本不打印其内容。而且字节无论如何都不是字符。为什么希望看到“hello”

你知道我为什么不打招呼的问题吗

byte f []  ="hello".getBytes();

System.out.println(f.toString());
因为
byte[]#toString()
通常不作为
new String(byteArray)
实现,这将导致您期望的结果(例如
System.out.println(new String(byteArray));


您可能想看一看…

因为字节数组的
toString
方法根本不打印其内容。而且字节无论如何都不是字符。为什么希望看到
“hello”
?为什么不执行
System.out.println(“hello”)
直接?

如果不提供编码方法,就无法在字节数组和字符串之间进行转换


试试
System.out.println(新字符串(f,“UTF8”);

System.out.println(f.toString())
中获得“奇怪”输出的原因是您正在打印数组,而不是字符串。Java的数组类不会覆盖
toString()
方法。因此,
toString()
正在调用的方法是来自
java.lang.Object
的方法,该方法被定义为输出对象的类名及其标识hashcode。(在这种情况下,
字节[]
类的类名将是“[b”。)

我认为你的困惑是因为你在心理上将字符串和字节数组等同起来。这在概念上是错误的原因有两个:

  • 在Java中,字符串不是任何东西的数组。字符串类是一个完全封装的类,不能转换为除Object之外的任何东西

  • 在Java中,字符串建模的是字符序列,而不是字节序列


后者是一个关键区别,因为字符序列和字节之间存在许多可能的转换,其中许多转换在一个或两个方向上都是有损的您可以获得平台默认字符编码所隐含的转换,但是您可以向
getBytes
提供一个参数,以便在转换中使用不同的编码。

因为
f
不是
字符串,而
是toString()
调用了
对象
类的方法,而不是
字符串
类的方法。
String的
toString
类返回一个
String
,而
对象的
toString
类返回:

getClass().getName()+'@'+Integer.toHexString(hashCode())
……哦,哦,不要走得太远……这和:
classname.@hexadecimal
哈希代码的代码

我想他是想了解java数组是如何工作的…?错了!你可以从
byte[]
在不指定编码的情况下使用字符串,就像在不指定编码的情况下使用其他方法一样。但这两种方法都不应该做。@Joachim:事实上,你不能。Java使用基于Unicode的字符模型,而这些模型与字节完全不对应。你所能做的就是使用默认转换,但这很糟糕。t他的整个混乱就是为什么java 1.1中添加了
java.io.Reader
等。@Donal:我非常了解java如何处理字符(以及字符到字节的转换)。您可以使用此构造函数将
byte
-数组转换为字符串:它将使用“平台默认字符集”这很可能不是你想要的,但它仍然是可能的。哦,我知道平台默认转换,但它们没有用处,因为一般来说,你不能获取任意字节序列或任意字符序列,将其转换为另一个并返回,并保证返回你开始使用的内容。两个方向可能会丢失信息,具体取决于系统默认的编码方式。(小心是值得的;如果从字符开始,则使用UTF-8,如果从字节开始,则使用ISO8859编码之一。)@Donal:当然它有问题,这就是我在最初的评论中“你不应该做[It]”的意思。但是“它有问题”与“你做不到”不同。无论你使用哪种编码(不包括BASE64和其他不是真正字符编码的编码),尝试将任意二进制数据转换为字符数据都是危险的。FWIW,
System.out.write(f);System.out.flush()
应该可以像预期的那样正常工作。而且可能还使用了
printf
的功能。