String.getBytes()方法中的中文编码问题(转)

String的getBytes()方法是得到一个系统默认的编码格式的字节数组
getBytes("utf-8") 
得到一个UTF-8格式的字节数组

把String转换成bytes,各种编码转换成的bytes不同,比如UTF-8每个汉字转成3bytes,而GBK转成2bytes,所以要说明编码方式,否则用缺省编码。

在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组。这表示在不同的操作系统下,返回的东西不一样!

String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如:
byte[]
b_gbk = "中".getBytes("GBK");
byte[] b_utf8 = "中".getBytes("UTF-8");
byte[] b_iso88591 = "中".getBytes("ISO8859-1");
将分别返回"中"这个汉字在GBK、UTF-8和ISO8859-1编码下的byte数组表示,此时

b_gbk的长度为2,

b_utf8的长度为3,

b_iso88591的长度为1。

而与getBytes相对的,可以通过new String(byte[],
decode)的方式来还原这个"中"字,

这个new String(byte[],
decode)实际是使用指定的编码decode来将byte[]解析成字符串
.
String s_gbk = new String(b_gbk,"GBK");
String s_utf8 = new String(b_utf8,"UTF-8");
String s_iso88591 = new String(b_iso88591,"ISO8859-1");
通过输出s_gbk、s_utf8和s_iso88591,会发现s_gbk和s_utf8都是"中",而只有s_iso88591是一个不被识别的字符(可以理解为乱码),为什么使用ISO8859-1编码再组合之后,无法还原"中"字?原因很简单,因为ISO8859-1编码的编码表根本就不包含汉字字符,当然也就无法通过"中".getBytes("ISO8859-1");来得到正确的"中"字在ISO8859-1中的编码值了,所以,再通过new
String()来还原就更是无从谈起。
因此,通过String.getBytes(String
decode)方法来得到byte[]时,一定要确定decode的编码表中确实存在String表示的码值,这样得到的byte[]数组才能正确被还原。

注意:

有时候,为了让中文字符适应某些特殊要求(如http
header要求其内容必须为iso8859-1编码),可能会通过将中文字符按照字节方式来编码的情况,如:
String
s_iso88591 = new
String("中".getBytes("UTF-8"),"ISO8859-1"),这样得到的s_iso8859-1字符串实际是三个在ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式String
s_utf8 = new
String(s_iso88591.getBytes("ISO8859-1"),"UTF-8")来得到正确的中文汉字"中",这样就既保证了遵守协议规定、也支持中文。

时间: 2024-10-29 19:12:24

String.getBytes()方法中的中文编码问题(转)的相关文章

String在方法中的传递方式(调用外部方法给String变量赋值时,未得到预期结果)

示例: public class StringTraining { public static void changeStr(String str){ str = "137878"; } public static void main(String[] args){ String a = "b"; changeStr(a); System.out.println(a); }} 输出仍旧为b 分析:首先栈中存的是堆中对象的地址,因为String对象的特殊性(Strin

java.lang.String.getBytes(String charsetName)方法实例

java.lang.String.getBytes(String charsetName) 方法编码将此String使用指定的字符集的字节序列,并将结果存储到一个新的字节数组. 声明 以下是java.lang.String.getBytes()方法的声明 public byte[] getBytes(String charsetName) throws UnsupportedEncodingException 参数 charset -- 这是一个支持的字符集的名称. 返回值 此方法返回得到的字节

深入解析String.intern()方法

转载: http://tech.meituan.com/in_depth_understanding_string_intern.html 引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念.常量池就类似一个JAVA系统级别提供的缓存. 8种基本类型的常量池都是系统协调的,String类型的常量池比较特殊.它的主要使用方法有两种: 直接使用双引号声明出来的String对象会直接存储在常量池中. 如

【转】String hashCode 方法为什么选择数字31作为乘子

某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途.后来带着疑问和好奇心,到网上去找资料查询一下.在看完资料后,默默的感叹了一句,原来是这样啊.那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜. 2. 选择数字31的原因 在详细说明 String hashC

String hashCode 方法为什么选择数字31作为乘子

1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主角31.这个数字居然不是用常量声明的,所以没法从字面意思上推断这个数字的用途.后来带着疑问和好奇心,到网上去找资料查询一下.在看完资料后,默默的感叹了一句,原来是这样啊.那么到底是哪样呢?在接下来章节里,请大家带着好奇心和我揭开数字31的用途之谜. 2. 选择数字31的原因 在详细说明 String

33.C#--方法中ref参数的使用

static void Main(string[] args){//方法中ref参数的使用,不考虑实用性,只讲ref使用方法//用ref实现奖金+500double salary = 5000;JiangJin(ref salary); //传实参Console.WriteLine("这个月的总工资是:{0}", salary);Console.ReadKey(); } public static void JiangJin(ref double s) //ref有自动返回功能 { s

Collection 和Collections的区别|、String的getBytes方法

1.比较Collection 和Collections的区别=====    (1).java.util.Collection 是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.Collection接口在Java 类库中有很多具体的实现.Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式.   (2)2.java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法.此类不能实例化,就像一个工具类,服务于Java的Collec

java中的String.getBytes()的用法

在Java中,String的getBytes()方法是得到一个操作系统默认的编码格式的字节数组.这个表示在不通OS下,返回的东西不一样! String.getBytes(String decode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示,如 byte[] b_gbk = "中".getBytes("GBK"); byte[] b_utf8 = "中".getBytes("UTF-8"); by

String的replaceAll方法中的正则表达式用法

项目里面 需要对已手机号码进行 如下的显示 比如15088688388 要显示为150****8388的效果 实现这个简单的效果 方法有很多 我想试试用正则表达式去实现 查了点资料最终试出来以下方法可行 System.out.println("15088688388".replaceAll("(\\d{3})(\\d{4})","$1****")); 输出结果:150****8388 首先对replaceAll方法的第一个参数进行解释 第一个参数