25
//与24类似,这不过
public byte[] getBytes(Charset charset) {
if (charset == null) throw new NullPointerException();
return StringCoding.encode(charset, value, 0, value.length);①
}
①
static byte[] encode(Charset cs, char[] ca, int off, int len) {
CharsetEncoder ce = cs.newEncoder();
int en = scale(len, ce.maxBytesPerChar());//获取可能达到的最长长度
byte[] ba = new byte[en];//创建一个绝对不会超出长度的数组,这部方法其实在日常项目中也可应用
//好处,不需要该数组的自增功能 1:可以增加性能,少一步提升之后还要复制数组的操作
//2:节省空间,自增后可能出现多余的空间根本用不到
if (len == 0)
return ba;//如果长度为0,就是空串,但是不会报错,没有转码的必要,直接返回
boolean isTrusted = false;
if (System.getSecurityManager() != null) {//检查系统安全管理器是否存在,有安全管理器在,这段要被转码
//的数据,可以降低被篡改的风险
if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {//判断是否被允许访问私有包
ca = Arrays.copyOfRange(ca, off, off + len);//如果安全管理器都没有,就不用判断是否允许了,执行可能会报错
off = 0;
}//这个复制的意义就是产生一个新的对象,防止因为该对象在其他的地方被用到了,放生了改变,产生的不可预知的情况
}
ce.onMalformedInput(CodingErrorAction.REPLACE)
.onUnmappableCharacter(CodingErrorAction.REPLACE)
.reset();//之前见过的工厂类型的初始化对象
if (ce instanceof ArrayEncoder) {
int blen = ((ArrayEncoder)ce).encode(ca, off, len, ba);
return safeTrim(ba, blen, cs, isTrusted);
} else {
ByteBuffer bb = ByteBuffer.wrap(ba);
CharBuffer cb = CharBuffer.wrap(ca, off, len);
try {
CoderResult cr = ce.encode(cb, bb, true);
if (!cr.isUnderflow())
cr.throwException();
cr = ce.flush(bb);
if (!cr.isUnderflow())
cr.throwException();
} catch (CharacterCodingException x) {
throw new Error(x);
}
return safeTrim(ba, bb.position(), cs, isTrusted);
}
}