众所周知:
char是一个16位二进制的Unicode字符,JAVA用char来表示一个字符 。
可能看到上面这句话的时候,往往不会在意char是不是Unicode字符,当时它却是我们理清楚编码的关键。
一说到编码,就会想到GBK和utf8,到底这些编码都是干什么的呢?
Charset.forName("Unicode")
,结果是UTF_16。byte[]是字节数组,而char[]是字符数组。
String的构造方法有根据字符数组和字节数组创建字符对象,StringBuilder中只有添加字符数组的方法。 String:
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
public String(byte bytes[]) {
this(bytes, 0, bytes.length);
}
public String(byte bytes[], String charsetName)
throws UnsupportedEncodingException {
this(bytes, 0, bytes.length, charsetName);
}
public String(byte bytes[], Charset charset) {
this(bytes, 0, bytes.length, charset);
}
StringBuilder:
public StringBuilder append(char[] str) {
super.append(str);
return this;
}
所以,有时候会疑惑,为什么StringBuilder不需要考虑编码的问题,这是因为StringBuilder本身是一个char[] value
.
而String本身也是个char value[]
,但是却将byte[]装成了char[]:
static char[] decode(String charsetName, byte[] ba, int off, int len)
throws UnsupportedEncodingException
{
StringDecoder sd = deref(decoder);
String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
|| csn.equals(sd.charsetName()))) {
sd = null;
try {
Charset cs = lookupCharset(csn);
if (cs != null)
sd = new StringDecoder(cs, csn);
} catch (IllegalCharsetNameException x) {}
if (sd == null)
throw new UnsupportedEncodingException(csn);
set(decoder, sd);
}
return sd.decode(ba, off, len);
}
所以,字符串就是存储的字符,不叫字节串,字节转字符需要指定编码,字符转字节也需要指定编码。
InputStream无论是网络流还是文件流,都是不需要自定编码,如:
public FileInputStream(String name) throws FileNotFoundException {
this(name != null ? new File(name) : null);
}
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
因为它本身就是字节,属于存储属性的字节,已经有编码含义。
InputStreamReader需要指定编码:
public InputStreamReader(InputStream in, String charsetName)
throws UnsupportedEncodingException
{
super(in);
if (charsetName == null)
throw new NullPointerException("charsetName");
sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
}
类似与String, 它需要将字节转成字符,就需要指定编码。
一个字就是一个字符,一个字可以有多个字节。不同的编码下,一个字的字节数不同。