1. 程式人生 > >java String類,底層自學自看 筆記(實時更新)2

java String類,底層自學自看 筆記(實時更新)2

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);
        }
}