Integer轉String

    Integer轉String的場景咱們在工做中會遇到不少,咱們今天來分析下有哪些方法,這些方法分別是怎麼實現的,有什麼區別。java

    咱們首先會想到的是類型強轉,格式如:(String)Integer。git

    

    咱們發現idea中編寫不經過,報錯:cannot cast 'java.lang.Integer' to 'java.lang.String'。數組

    第二種方式調用Object.toString()方法。toString()方法是超類Object提供的方法,Integer確定也含有該方法, 不過Integer對這個方法進行了重寫。咱們先來運行Integer.toString()方法,而後再來具體分析該方法。app

public static void main(String[] args){
        Integer var = new Integer(10);
        String str = var.toString();
        System.out.println(str);
}

    執行結果爲10,沒問題。咱們先來看下Object.toString()方法。ide

public String toString() {
      return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

public native int hashCode();

    Integer重寫了Object.toString()方法。ui

private final int value;
@Native public static final int   MIN_VALUE = 0x80000000;
@Native public static final int   MAX_VALUE = 0x7fffffff;

public String toString() {
        //經過Integer類的成員變量value去獲取String值
        return toString(value);
}

public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        //若是i是正整數,返回這個數是幾位數,若是是負數,取負數的絕對值位數加一,好比是-23,size爲3
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
        //根據Integer的位數,建立一個該位數大小的char數組
        char[] buf = new char[size];
        //獲取Integer值對應的char數組
        getChars(i, size, buf);
        //經過new String()構造方法將char數組轉換爲String
        return new String(buf, true);
}

//x小於等於9,返回1
//x小於等於99,返回2
//按此規律返回x是幾位數
//若是x是負數,返回1
static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
}

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };

//經過參照碼錶digits,將Integer i的每一位都放到char數組中
static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        //若是i小於0,字符前面加負號,i取絕對值
        if (i < 0) {
            sign = '-';
            i = -i;
        }

        // Generate two digits per iteration
        while (i >= 65536) {
            q = i / 100;
        // really: r = i - (q * 100);
            r = i - ((q << 6) + (q << 5) + (q << 2));
            i = q;
            buf [--charPos] = DigitOnes[r];
            buf [--charPos] = DigitTens[r];
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) {
            q = (i * 52429) >>> (16+3);
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign;
        }
}

final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };

    經過研究Integer的源碼咱們發現Integer轉String的主要思路是先得到Integer的位數,若是是負數,就是這個數的絕對值的位數加一(負號佔一位),而後根據位數建立一個char數組,將Integer的每一位都放到char數組中,最後經過String的new String(Char[] char,boolean share)構造方法建立字符串。idea

    第三種方式是String類提供的靜態方法String.valueOf(Integer i )spa

Integer var = new Integer(10);
String str = String.valueOf(var);

    看下String類中String.valueOf(Integer i )的底層源代碼。插件

public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
}

    咱們看到底層仍是調用的Integer.toString()方法。這裏有一點咱們須要注意的是String類的valueOf()方法,若是傳入值是null,返回值是「null」,而不是null。3d

    第四種方式Integer+""方式,就是在Integer的變量值後面加上一個空字符串。

Integer var = new Integer(10);
String str = var+"";
System.out.println(str);

    這個代碼得去看字節碼文件分析。咱們能夠使用javap命令或者idea提供的jclasspath插件查看。文件內容以下所示:

0 new #2 <java/lang/Integer>
 3 dup
 4 bipush 10
 6 invokespecial #3 <java/lang/Integer.<init>>
 9 astore_1
10 new #4 <java/lang/StringBuilder>
13 dup
14 invokespecial #5 <java/lang/StringBuilder.<init>>
17 aload_1
18 invokevirtual #6 <java/lang/StringBuilder.append>
21 ldc #7
23 invokevirtual #8 <java/lang/StringBuilder.append>
26 invokevirtual #9 <java/lang/StringBuilder.toString>
29 astore_2
30 getstatic #10 <java/lang/System.out>
33 aload_2
34 invokevirtual #11 <java/io/PrintStream.println>
37 return

    咱們發現字節碼文件中是建立StringBuilder,經過StringBuilder.append()方法將Integer類型的var和空字符串""鏈接起來的,至關於下面的java流程:

Integer var = new Integer(10);
StringBuilder builder = new StringBuilder();
builder.append(var);
builder.append("");
String str = builder.toString();
System.out.println(str);

    再看下builder.append(var)的底層代碼:

@Override
public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

    StringBuilder的append(Object obj)方法裏是先經過String.valueOf()方法將obj轉換爲String類型,而後再調用append方法。而String.valueOf()方法最終仍是調用的Integer類的toString()方法。

    結合三種方式咱們發現最終都是落到了Integer類的toString()方法上來了,那麼咱們在實際寫代碼中遇到Integer轉String類型的時候不妨就直接調用Integer的toString()方法了。

相關文章
相關標籤/搜索