黑马程序员技术交流社区

标题: String类的面试题,求解答 [打印本页]

作者: 漠然~回首℃    时间: 2014-3-12 12:47
标题: String类的面试题,求解答
byte[] arr = {65,66,67};
String s2 = new String(arr);
System.out.println(s2);
//结果为什么是A,B,C
我知道这是对应的码表值,但是在new  String(arr)里面是怎么转换的啊


作者: tangxiaobo1991    时间: 2014-3-12 13:19
在java的api中定义了string类中的一个构造方法string(byte[] bytes),返回值是string。这个方法的功能就通过平台默认的字符集(即ascii码)解码指定的byte[]数组,产生一个指定的字符串(根据前面的解码而来的)。。所以明显上面打印的是通过解码的字符串阿。
作者: 透过生活    时间: 2014-3-12 13:47
String(byte[] bytes)
          通过使用平台的默认字符集解码指定的 byte 数组,构造一个新的 String。
这是Java API里 String这个类中的构造方法,接受一个byte数组,返回一个新的String。
建议多查查API,很多方法是不用死记的,查查就能知道怎么用。

作者: 咸鱼    时间: 2014-3-12 13:47
String类源码:
private final char value[];//String对应的字符数组容器
public String(byte bytes[]) {
        this(bytes, 0, bytes.length);//继续调用本类构造器
    }
public String(byte bytes[], int offset, int length) {
        checkBounds(bytes, offset, length);//检查是否越界
        this.value = StringCoding.decode(bytes, offset, length);//调用StringCoding类方法
    }
StringCoding类源码:
static char[] decode(byte[] ba, int off, int len) {
        String csn = Charset.defaultCharset().name();//字符集
        try {
            // use charset name decode() variant which provides caching.
            return decode(csn, ba, off, len);//执行到这里跳转
        } catch (UnsupportedEncodingException x) {
            warnUnsupportedCharset(csn);
        }
        try {
            return decode("ISO-8859-1", ba, off, len);//字符集编码
        } catch (UnsupportedEncodingException x) {
            // If this code is hit during VM initialization, MessageUtils is
            // the only way we will be able to get any kind of error message.
            MessageUtils.err("ISO-8859-1 charset not available: "
                             + x.toString());
            // If we can not find ISO-8859-1 (a required encoding) then things
            // are seriously wrong with the installation.
            System.exit(1);
            return null;
        }
    }
static char[] decode(Charset cs, byte[] ba, int off, int len) {    //编码阶段
        CharsetDecoder cd = cs.newDecoder();
        int en = scale(len, cd.maxCharsPerByte());
        char[] ca = new char[en];
        if (len == 0)
            return ca;
        boolean isTrusted = false;
        if (System.getSecurityManager() != null) {
            if (!(isTrusted = (cs.getClass().getClassLoader0() == null))) {
                ba =  Arrays.copyOfRange(ba, off, off + len);
                off = 0;
            }
        }
        cd.onMalformedInput(CodingErrorAction.REPLACE)
          .onUnmappableCharacter(CodingErrorAction.REPLACE)
          .reset();
        if (cd instanceof ArrayDecoder) {
            int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);
            return safeTrim(ca, clen, cs, isTrusted);
        } else {
            ByteBuffer bb = ByteBuffer.wrap(ba, off, len);
            CharBuffer cb = CharBuffer.wrap(ca);
            try {
                CoderResult cr = cd.decode(bb, cb, true);
                if (!cr.isUnderflow())
                    cr.throwException();
                cr = cd.flush(cb);
                if (!cr.isUnderflow())
                    cr.throwException();
            } catch (CharacterCodingException x) {
                // Substitution is always enabled,
                // so this shouldn't happen
                throw new Error(x);
            }
            return safeTrim(ca, cb.position(), cs, isTrusted);
        }
    }
private static char[] safeTrim(char[] ca, int len,            //通过编码确定安全的截取长度
                                   Charset cs, boolean isTrusted) {
        if (len == ca.length && (isTrusted || System.getSecurityManager() == null))
            return ca;
        else
            return Arrays.copyOf(ca, len);
    }
作者: 一年_Hei    时间: 2014-3-12 13:50
你这里是调用了String类有一个构造方法,接收一个字节数组,创建一个字符串对象。 A B C 就是你说的码表值
作者: 何伟超    时间: 2014-3-12 13:58
Java1.5新特性吧
作者: 战狼    时间: 2014-3-12 23:01
简单点,你的s是一个字符串类型的变量,而你的arr是一个字节型的变量,当你运行是,系统会自动将字节型变量转换为字符串变量,并且输出




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2