java .getbytes_Java GetBytes 编码方式

在JAVA源文件-->JAVAC-->Class-->Java-->getBytes()-->new String()-->显示的过程中,每一步都有编码的转换过程,这个过程总是存在的,只是有的时候用默认的参数进行。

1.  JAVAC是以系统默认编码读入源文件,然后按UNICODE进行编码的。可以通过指定编码方式改变Javac读入源文件的编码方式。

Java代码  9cdbeb1c12ac6e53582a53a7f482f126.png

javac -encoding GBK Test.java

2. 在JAVA运行的时候,JAVA也是采用UNICODE编码的,并且默认输入和输出的都是操作系统的默认编码。

也就是说在new String(bytes[,encode])中,系统认为输入的是编码为encode的字节流,换句话说,如果按encode来翻译bytes才能得到正确的结果,这个结果最后要在JAVA中保存,它还是要从这个encode转换成Unicode,也就是说有bytes-->encode字符-->Unicode字符的转换;而在String.getBytes([encode])中,系统要做一个Unicode字符-->encode字符-->bytes的转换。

3. Java中的编码支持

Java是支持多国编码的,在Java中,字符都是以Unicode进行存储的,比如,“你”字的Unicode编码是“4f60”,我们可以通过下面的实验代码来验证:

Java代码  9cdbeb1c12ac6e53582a53a7f482f126.png

class TestCharset          {

public static void main(String[] args)

{

char c = '你';

int i = c;

System.out.println(c);

System.out.println(i);

}

}

不管你在任何平台上执行,都会有相同的输出:20320,20320就是Unicode “4f60”的整数值。其实,你可以反编译上面的类,可以发现在生成的.class文件中字符“你”(或者其它任何中文字串)本身就是以Unicode编码进行存储的:char c = '\u4F60';

4. 为了避免这种问题,建议大家都在编码中使用String.getBytes(String charset)方法。

Java代码  9cdbeb1c12ac6e53582a53a7f482f126.png

class TestCharset {

public static void main(String[] args) {

new TestCharset().execute();

}

private void execute() {

String s = "Hello!你好!";

byte[] bytesISO8859 =null;

byte[] bytesGBK = null;

try

{

bytesISO8859 =

s.getBytes("iso-8859-1");

bytesGBK = s.getBytes("GBK");

}

catch

(java.io.UnsupportedEncodingException e)

{

e.printStackTrace();

}

System.out.println

("--------------\n 8859 bytes:");

System.out.println("bytes is:     " + arrayToString(bytesISO8859));

System.out.println("hex format is:"

+ encodeHex(bytesISO8859));

System.out.println();

System.out.println

("--------------\n GBK bytes:");

System.out.println("bytes is:" + arrayToString(bytesGBK));

System.out.println("hex format is:" + encodeHex(bytesGBK));

}

public static final String

encodeHex (byte[] bytes)

{

StringBuffer buff =

new StringBuffer(bytes.length * 2);

String b;

for (int i=0; i

{

b = Integer.toHexString(bytes[i]);

// byte是两个字节的,而上面的Integer.toHexString会把字节扩展为4个字节

buff.append(b.length() > 2 ? b.substring(6,8) : b);

buff.append(" ");

}

return buff.toString();

}

public static final String arrayToString(byte[] bytes) {

StringBuffer buff = new StringBuffer();

for (int i = 0; i 

buff.append(bytes[i] + " ");

}

return buff.toString();

}

}

执行上面程序将打印出:

--------------

8859 bytes:

bytes is: 72 101 108 108 111 33 63 63 63

hex format is:48 65 6c 6c 6f 21 3f 3f 3f

--------------

GBK bytes:

bytes is: 72 101 108 108 111 33

-60 -29 -70 -61 -93 -95

hex format is:48 65 6c 6c 6f 21 c4 e3 ba c3 a3 a1

可见,在s中提取的8859-1格式的字节数组长度为9,中文字符都变成了“63”,ASCII码为63的是“?”,一些国外的程序在国内中文环境下运行时,经常出现乱码,上面布满了“?”,就是因为编码没有进行正确处理的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值