java编码总结1

java字符串编码问题在遇到乱码情况下也看过一些原理,但是没有仔细研究过,最近项目中用到socket接收字节数组转换字符串,所以算是仔细地研究了下,不太深入,根据例子所总结。

 

一、String类有很多构造方法,最近常用到的有两种,String(byte[] bytes)和String(byte[] bytes, String charsetName)。第一个是根据byte数组按照系统默认的编码方式生成字符串;第二个是根据byte数组按照指定编码方式生成字符串。

 

例子中byte数组是字符串“@中文”的gbk编码数组(可以根据gbk编码对照表查看),我本机是win7操作系统,系统默认gbk编码。

1)按系统默认编码方式:

public static void main(String[] args) {

		byte[] b = new byte[] { 64, (byte) 0xD6, (byte) 0xD0, (byte) 0xCE,(byte) 0xC4 };
		System.out.println(new String(b));
	}

运行结果:@中文

 

2)按照指定编码格式方式:

 

public static void main(String[] args) {
		byte[] b = new byte[] { 64, (byte) 0xD6, (byte) 0xD0, (byte) 0xCE,(byte) 0xC4 };
		try {
			System.out.println(new String(b,"utf-8"));
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

 运行结果:@????

 

总结:

由于我的byte数组定义时为gbk编码量身打造,所以1)中输出正确。2)中utf-8编码只能识别数组中的第1位‘@’字符,另外几个数组识别不了,所以每个字节解释为‘?’。

看似很简单的demo,其实从生成字符串到打印到控制台经历了几个步骤。如下:

byte[]--->根据编码方式生成String--->String在jvm中保存为unicode编码格式--->System.out.println()按照系统默认编码把字符串打印到控制台--->控制台按照指定编码(默认系统编码)查看字符串。

根据此步骤分析1):

b--->"@中文"--->6位字节的unicode编码格式byte数组(jvm)--->5位gbk编码格式byte数组--->控制台以gbk格式查看会看到"@中文"

其中示例2)中在步骤2时已经得到乱码字符串"@????",所以会在控制台看到乱码。

 

二、String类中有两个获取字节数组的方法,getBytes()和getBytes(String charsetName),第一个是获取字符串系统默认编码方式的byte数组。第二个则是获取字符串指定编码方式格式的byte数组。

 

1)根据系统默认方式获取

 

public static void main(String[] args){

		String s = "@中文";
		System.out.println(s.getBytes().length);
	}

 

运行结果:5

 

2)根据指定(utf-8)编码方式获取:

 

 

	public static void main(String[] args){
		String s = "@中文";
		try {
			System.out.println(s.getBytes("utf-8").length);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

 

运行结果:7

 

总结:示例1)根据gbk编码获取,gbk编码中文两个字节,因此长度为5.

示例2)根据utf-8编码获取,utf-8编码中文三个字节,因此长度为7.

 

有兴趣可以把不同编码方式得到的字节数组中每个字节的int类型打印出来,跟编码表比对一下。

 

java乱码问题涉及到很多方面,这里只是分析String最基础的部分,其他的会在有时间时再研究。

 

附件中包含了gbk、unicode和asc编码表格。有兴趣可以看下。

 

你可能感兴趣的:(J2se,java,编码)