




1 Integer a = 34;
2 int b = 34;
3 Integer c = b;
4 int d = a;
5 System.out.println( a == b);
6 System.out.println( d == c);
基本数据类型的和其包装类的相互转换,这是为什么呢? 答案很简单,因为我们在执行Integer a = 34; 代码时jdk默认执行的是
Integer a = Integer.valueOf(34);
而我们在执行int d = a;时编译执行的却是
int d = a.intValue();
你可能会有疑问,为什么会是这样? 这个时候我们就需要打开源码进行查看寻找答案。
1 /**
2 * Returns an {@code Integer} instance representing the specified
3 * {@code int} value. If a new {@code Integer} instance is not
4 * required, this method should generally be used in preference to
5 * the constructor {@link #Integer(int)}, as this method is likely
6 * to yield significantly better space and time performance by
7 * caching frequently requested values.
8 *
9 * This method will always cache values in the range -128 to 127,
10 * inclusive, and may cache other values outside of this range.
11 *
12 * @param i an {@code int} value.
13 * @return an {@code Integer} instance representing {@code i}.
14 * @since 1.5
15 */
16 public static Integer valueOf(int i) {
17 if (i >= IntegerCache.low && i <= IntegerCache.high)
18 return IntegerCache.cache[i + (-IntegerCache.low)];
19 return new Integer(i);
20 }
文档是这样说的,返回一个制定int数值的Integer对象实例,这样好像还不足以说明什么,那我们要如何证明我们是对的呢? 我们可以查看他的编译文件,一切就真相大白了(javac命令)。
1 public static void main(String[] var0) {
2 new User();
3 Integer var2 = Integer.valueOf(34);
4 byte var3 = 34;
5 Integer var4 = Integer.valueOf(var3);
6 int var5 = var2.intValue();
7 System.out.println(var2.intValue() == var3);
8 System.out.println(var5 == var4.intValue());
9 }
这好像就不需要我在多说什么了。 细心的小伙伴会看到文档里面有这么一句话 * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range.该方法会缓存-128到127之间的值,这句话又是什么意思呢。
1 Integer a = 120;
2 Integer b = 120;
3 Integer c = 300;
4 Integer d = 300;
5 System.out.println( a == b);
6 System.out.println( d == c);
这两句代码会输出社么呢,小伙伴们肯定说都是true啊,或者说都是false。会这样说的小伙伴不能说你错了,只能说你对了一半;是这样的啊,我们知道==运算符进行运算时,运算符两边如果都为基本数据类型的话那就直接对数值进行比较;但是如果两边或者一边为非基本数据类型时,即对象实例,则比较的是他们的内存地址(如果为空对象的话则为null),这里很明显两边都是对象实例,所以比较的是内存地址。






Integer b = Float.valueOf(a).intValue();
好像行了,测试一下。

1 /**什么,居然是个强转,搞了半天还是强转,那为啥我们那样转不行呢,因为我们是类强转,而它是类型转换。
2 * Returns the value of this {@code Float} as an {@code int} after
3 * a narrowing primitive conversion.
4 *
5 * @return the {@code float} value represented by this object
6 * converted to type {@code int}
7 * @jls 5.1.3 Narrowing Primitive Conversions
8 */
9 public int intValue() {
10 return (int)value;
11 }

1 Long start = System.currentTimeMillis();
2 Long l = 0L;
3 for (Integer i = 0; i < Integer.MAX_VALUE; i++){
4 l++;
5 }
6 System.out.println(System.currentTimeMillis() - start);
这段代码会执行多久呢,好像是一瞬间的事,可是他执行了13060ms,可能这关系到机器,但是这个问题是很严重的,如果不小心写了这样的代码,搞蹦一个程序是很简单的事情。 这里每次执行l++操作其实都相当于创建了一个新的实例,那这个量就非常大了,而如果换成基本数据类型的话,从始至终它都是8个字节。 我们修改一下程序
1 Long start = System.currentTimeMillis();
2 long l = 0L;
3 for (int i = 0; i < Integer.MAX_VALUE; i++){
4 l++;
5 }
6 System.out.println(System.currentTimeMillis() - start);
那么它的运行时间又是多少呢?78ms 是不是很惊讶,相差了好几百倍,所以我们绝对不可以出现这样的代码,对于基本数据类型还是包装类的选择,我们首选还是基本数据类型,而当某些场景无法继续使用基本数据类型时,我们才使用包装类进行处理。 OK,到此为止,基本数据类型跟包装类之间的关系和区别我就讲完了,如果有讲的不好或者是讲得不对的地方大家一定要指出来,不然我就没法进步了。
到时候博客开通了,还需要各位老少爷们捧场哈。
作者: 小丑鱼yang
链接:http://www.imooc.com/article/17521 来源:慕课网