Java ObjectOutputStream';s writeObject方法的使用?

Java ObjectOutputStream';s writeObject方法的使用?,java,character-encoding,utf-16,fileoutputstream,objectoutputstream,Java,Character Encoding,Utf 16,Fileoutputstream,Objectoutputstream,我听说Java在内部使用UTF-16编码。i、 e.我理解如果我有like:String var=”जनमत"; 然后是“जनमत“将在内部以UTF-16编码。因此,如果我将此变量转储到以下文件中: fileOut = new FileOutputStream("output.xyz"); out = new ObjectOutputStream(fileOut); out.writeObject(var); “将更改字符串的编码”जनमत“在文件“output.xyz”中是否在UTF-16中

我听说Java在内部使用UTF-16编码。i、 e.我理解如果我有like:String var=”जनमत"; 然后是“जनमत“将在内部以UTF-16编码。因此,如果我将此变量转储到以下文件中:

fileOut = new FileOutputStream("output.xyz");
out = new ObjectOutputStream(fileOut);
out.writeObject(var);
“将更改字符串的编码”जनमत“在文件“output.xyz”中是否在UTF-16中?另外,稍后如果我想通过ObjectInputStream从文件“output.xyz”中读取,我是否能够获得变量的UTF-16表示形式


谢谢。

关闭:它不完全是UTF-16,而是类似于UCS-2;但无论哪种方式,大多数字符都使用2个字节(2个字符的序列,即一些很少使用的代码点使用4个字节)

ObjectOutputStream使用一种叫做修改的UTF-8的东西,它类似于UTF-8,但零字符表示为2字节序列,这在UTF-8中是不合法的(由于编码的唯一性限制),但这种类型的字符自然会解码回值0

但你们真正要问的是“我写一个字符串,读一个字符串,它能工作吗”——答案是肯定的。JDK在写字节时进行正确的编码,在读时进行解码

值得一提的是,您最好对字符串使用“writeUTF()”方法,因为我认为结果输出更紧凑。但是“writeObject()”也可以工作,只需要更多的元数据

因此,如果我将此变量转储到某个文件中…字符串的编码是否会जनमत文件“output.xyz”中的“”是否为UTF-16格式

文件中字符串的编码将采用
ObjectOutputStream
希望采用的任何格式。您应该将其视为只能由
ObjectOutputStream
读取的黑盒。(说真的——即使格式是IIRC,如果您想用其他工具读取它,您应该自己将对象序列化为XML或JSON或其他任何形式。)

稍后,如果我想通过ObjectInputStream从文件“output.xyz”中读取,我是否能够获得变量的UTF-16表示形式

如果您使用
ObjectInputStream
读取文件,您将获得原始对象的副本。这将包括
java.lang.String
,这只是一个字符流(而不是字节),如果您愿意,可以通过该方法从中获得UTF-16表示(尽管我怀疑您实际上不需要)



总之,不要太担心序列化的内部细节。如果您需要知道发生了什么,请自己创建文件;如果您只是好奇,请相信JVM会做正确的事情。

再加上这一点,
ObjectOutputStream.writeString()
将确定给定字符串的UTF长度,并将其写入“标准”UTF或“长”UTF格式,其中“长”如javadoc中所述

“长”UTF格式与 标准UTF,但它使用8 字节头(而不是标准的2 字节)来传递UTF编码 长度

我从密码里得到这个

private void writeString(String str, boolean unshared) throws IOException {
    handles.assign(unshared ? null : str);
    long utflen = bout.getUTFLength(str);
    if (utflen <= 0xFFFF) {
        bout.writeByte(TC_STRING);
        bout.writeUTF(str, utflen);
    } else {
        bout.writeByte(TC_LONGSTRING);
        bout.writeLongUTF(str, utflen);
    }
}

我认为您不应该关心
ObjectOutputStream
所使用的编码。如果您要在其他地方使用生成的文件,请不要使用
ObjectOutputStream
。否则,您不必考虑它。您真的不应该直接在.java源文件中放入非ASCII字符,这一点在这里和其他地方已经讨论过了基本上,.java文件没有与它们相关的元数据来告诉它们编码的是哪种编码,也没有任何规范要求任何特定的编码。因此,当你混合使用操作系统、IDE、文本编辑器、工具(批处理/shell脚本)时,sh!t迟早会引起轰动,等等。您应该始终将非ASCII字符外部化到其他文件(您可以完全控制其编码)或使用\uxxx Java转义。要回答您的问题,不,事实是Java可能使用UTF-16或UCS-2(或者不太害怕穿的月靴颜色)在内部存储字符串对将所述字符串保存到文件时使用的编码没有任何影响。
if (obj instanceof String) {
    writeString((String) obj, unshared);
}