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()方法了。