字符集可以理解成一个对照表,某种编码规则的字符集规定:机器内某个长度一定二进制数表示代表一个对应的字符;
例如:
iso8859-1 :iso8859-1是采用单字节编码的,主要表示英文字母、字符,总范围的长度:256,由于汉字有成千上万个,所以该字符集不支持汉字编码。
双字节编码GBK、unicode等等,这些不同的编码规则使用的字节数也不等。
由于不同的字符集编码的长度各自不同,所以在涉及字符串与byte数组相互转换时,必须指定固定的字符集(并且指定的字符集必须支持该字符,例如使用iso8859-1编码汉字时就会GG),若传输一个byte前后使用不同的字符集编码,那么导致的问题是,可能在接收方无法得到与发送方相同的内容:
以GBK和iso8859-1测试为例:
PS*代码其实很简单,可以直接看完运行结果再回来瞟一眼
import java.io.UnsupportedEncodingException;
import java.util.regex.Pattern;
/**
* A collection of utilities relating to InetAddresses.
*/
public class Character {
public static void main(String[] args){
String ips = new String("一");
System.out.println("原内容:"+ips);
System.out.println();
byte[] ip = null;
try {
System.out.println("使用iso8859-1字符集将该汉字转为byte数组并打印");
ip = ips.getBytes("iso8859-1");
for(byte b:ip){
System.out.print(b+"(");
printByte(b);
System.out.print(")");
}
System.out.println();
System.out.println("对该byte数组使用iso8859-1字符集转为String:");
String addr1 = new String(ip,"iso8859-1");
System.out.println(addr1);
System.out.println();
System.out.println("使用gbk字符集将该汉字转为byte数组并打印");
ip = ips.getBytes("gbk");
for(byte b:ip){
System.out.print(b+"(");
printByte(b);
System.out.print(")");
}
System.out.println();
System.out.println("对该byte数组使用gbk字符集转为String:");
String addr2 = new String(ip,"gbk");
System.out.println(addr2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//以二进制的形式打印一个byte
public static void printByte(byte b){
byte[] p = new byte[8];
for(int i = 0;i<8;i++){
p[i] = (byte)(b & (byte)0x01);
b = (byte)((byte)b>>1);
}
for(int i =0;i<8;i++){
System.out.print(p[7-i]);
}
System.out.print(",");
}
}
iso8859-1并不支持汉字编码,所以得到的结果只有一个字符:"?"
而当使用字符集GBK把String类型的汉字"一"转为byte数组时,我们会发现,该汉字被拆分为一个长度为2的byte数组(所以可以证明GBK是双字节编码),当重新使用该byte数组使用gbk字符集转为String后打印也得到了对应的汉字:"一"。使用不同于gbk字符集的utf-8字符集转化该byte数组为String时的输出结果就成了乱码,所以选择的字符集一定要对应。
到此我对各种字符集编码的具体细节还是略显模糊,不过关于对字符集的理解已经足够我短时间内的使用了,或许以后有一天我需要继续对他进行学习,那时应该是去看它的编码规则了吧。
以下为使用byte数组构造String的两个构造函数: