StringBuffer类和中文字符编码

3
我编写了一个方法,用于返回包含中文字符的字符串。
public printChineseMenu(){
   StringBuffer buffer;
   buffer.append(chinese string returned from DB);     //chinese characters appear in SQL
   System.out.println(buffer);                         //they appear as question marks
   PrintStream out = new PrintStream(System.out, true, "UTF-8");
   out.println(buffer);                                //chinese characters appear

   return (buffer.toString())
}

有没有比StringBuffer类更好的类型来存储/返回中文字符字符串?


2
请不要使用StringBuffer,它在十年前就被StringBuilder替代了。 - Peter Lawrey
在您的问题中包含可编译的代码总是很好的。您所编写的代码存在一些问题。请尝试生成一个简洁的示例,以实际演示问题:请参阅http://stackoverflow.com/help/mcve。 - Duncan Jones
@Peter StringBuilder有特殊编码以保留中文字符吗? - bouncingHippo
@bouncingHippo:不需要。 - Jon Skeet
1
@ginz 请不要编辑别人问题中的代码。你的编辑应该被拒绝。 - Duncan Jones
显示剩余4条评论
2个回答

4
这里的问题不在于StringBuffer,而是System.out使用的编码方式。如果直接打印字符串而不使用StringBuffer,你会发现完全相同的行为。
StringBuffer(及其更现代的非线程安全等价物StringBuilder,应该使用它)本身并不关心编码,它们只使用UTF-16代码单元序列。它们将正确保留所有Unicode数据。对于String也是如此。
你的方法几乎肯定只需要返回一个String - 但如果您不需要使用StringBuffer或StringBuilder进行任何"构建"操作,则没有使用它们的必要。如果您确实需要从多个字符串构建结果字符串,则可以放心地使用它们,并像您已经做的那样返回toString()的结果(尽管返回值周围的括号无关紧要; return不是一个方法)。
控制台在处理字符串数据时常常会产生误导。如果有疑问,请逐个打印UTF-16代码单元序列,然后计算其含义。这样就不会出现编码或不可打印字符成为问题的危险。

3
你最好的选择是返回一个字符串。因为 String 是不可变的,并且可以存储比单个字符更多的信息。
当你打印文本时,你需要确保使用与尝试读取它期望的相同编码来写入数据。例如,如果你将输出重定向到文件并且你的阅读器期望 UTF-8 编码,那么你就应该这样写。 System.out 单独使用的问题在于它不会写入 char,而是写入 byte 并假定一种编码,这可能不是你所需要的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接