⑴ java两个Integer中为什么得出的结果为false
当然是false了,因为你定义了两个Integer对象 i 和 j,“==”在用于两个对象之间比较时,比较的是两个对象的地址,而不是值。
i 和 j分别是两个Integer对象,在内存中的地址当然不一样,所以比较结果是false。
用int来定义的话,比较的就是值,结果就是true了。
⑵ JAVA中int和Integer在内存中到底存在哪里
java被执行的时候,运行的是字节码,所以 你要看它到底做了什么 最好看字节码,而不是你的程序。这个自动装箱拆箱会在后面做一些事情,从你的代码中可能看不到。
所以反汇编成字节码后,你会看到a==b到底是做了什么呢?
25: iload_1
26: aload_2
27: invokevirtual #31 // Method java/lang/Integer.intValue:()I
30: if_icmpne 37
注意,你这里的a==b其实 对于b来说 调用了b.intValue()方法。因此 只是做了 int的比较。和存在哪里没有关系。这和自动装箱拆箱有关。
⑶ java包装类的比较,Integer i1 = 40; Integer i2 = 0 + 40;
Integer是一个包装类,里面包含一个intValue,你可以看下底层代码,你的几次声明和赋值都是一个40的int结果对象,输出比较结果肯定是相同的,所以返回true
⑷ Integer中的问题
……LZ很有意思。
System.out,println(a=b);
这一句话中有两个bug,应该是
System.out.println(a==b);
另外这个问题确实是这样的,Integer会自动缓存[-128,127]之间的Integer对象。不过你如果这么写:
Integer a = new Integer(126);
Integer b = new Integer(126);
System.out.println(a==b);
输出false
⑸ Java 的Integer,int与new Integer到底怎么回事
实例分析
先看一个例子。
[java]view plain
publicclassTest{
publicstaticvoidmain(String[]args){
Integeri=newInteger(128);
Integeri2=128;
System.out.println(i==i2);
Integeri3=newInteger(127);
Integeri4=127;
System.out.println(i3==i4);
Integeri5=128;
Integeri6=128;
System.out.println(i5==i6);
Integeri7=127;
Integeri8=127;
System.out.println(i7==i8);
}
}
- 输出的结果为
false
false
false
true
- 我们一个一个的进行分析。
Integeri=newInteger(128);
Integeri2=128;
- i 是创建的一个Integer的对象,取值是128。
- i2 是进行自动装箱的实例,因为这里超出了-128--127的范围,所以是创建了新的Integer对象。
Integeri3=newInteger(127);
Integeri4=127;
- i3 是创建的一个Integer的对象,取值是127.
Integeri5=128;
Integeri6=128;
Integeri7=127;
Integeri8=127;
- i7、i8是自动装箱产生的对象,其值都是127,那么这里很特殊的是127正好在-128<=i7<=127这个范围内的,那么会去IntegerCache中取,既然都是去IntegerCache中去取,那么自然该对象应该是一个对象,那么再堆中的地址应该是一样的,所以在判读两个对象是不是== 的时候,会输出true
[java]view plain
第一个情况:
[java]view plain
那么i和i2都是Integer的对象咯。存储在堆中,分配的地址不同,在使用==进行判读的时候,由于双方都是对象,所以比较对象的地址是不是相同,这里的地址是不同的,因为new的时候会在堆中重新分配存储空间。
第二个情况:
[java]view plain
i4 是进行自动装箱后生成的Integer的对象,其值-128<= i4 <= 127,所以在这里会与第一种情况有所不同,这个i4对象直接取缓存IntegerCache中的对应的对象,当然了也是对象。
那么i3和i4也都是对象咯,而且一个是缓存中的,一个自己new的,既然是对象那么==会比较其地址,因为都new出来的对象(一个是自己new出来的,一个是IntegerCache中new出来的对象),那么自然这两种情况下,在堆中分配的地址是不同的。
第三种情况:
[java]view plain
i5是自动装箱产生的Integer的对象,但是其大小超过了范围:-128<=A <=127,那么,这里会直接自己创建该对象即:new Integer(128);
i6和i5类似的原理。
显然这两个对象都是new出来,在堆中的地址值是不同的,那么==的时候判读其地址是不是相等,也就不一样了。
第四种情况:
[java]view plain
源码解析
下面看下,Integer中的装箱的代码
⑹ java swap(Integer a ,Integer b)实现交换
public class App {
public static void main(String[] args) {
Integer a=1, b=2;
System.out.println("before:a=" + a + ", b=" + b);
swap(a,b);
System.out.println("after:a=" + a + ", b=" + b);
}
public static void swap(Integer i1, Integer i2) {
Integer tmp = i1;
i1 = i2;
i2 = tmp;
}
}
输出结果:a=1,b=2
java里两种参数传递形式:值传递,引用传递
java变量分为基本类型,引用类型,两种类型的参数传递给方法时都是按值传递
形参和实参所占的内存地址不一样
形参中的内容只是实参中存储的对象引用的一份拷贝
交换的是两个引用变量的副本,原来的a,b引用指向不变。
请查看Integer.java
private final int value;
public Integer(int value) {
this.value = value;
}
public class App {
public static void main(String[] args) {
Integer a=1; // Integer a = Integer.valueOf(1); IntegerCache.cache[1+128] == 1
Integer b=2;
System.out.println("before: a=" + a + ", b=" + b);
swap(a, b);
System.out.println("after: a=" + a +", b=" + b);
}
public static void swap(Integer i1, Integer i2) throws NoSuchFieldException {
//通过反射获得类私有不可变变量(private final int value;)
Field field = Integer.class.getDeclaredField(name:"value");
//通过setAccessible去访问私有的成员变量
field.setAccessible(true);
int tmp = i1.intValue(); //tmp值是1,
field.set(i1, i2.intValue()); // i1的值设置为Integer.valueOf(i2.intValue()).intValue(),此时i1地址是IntegerCache.cache[1+128]: 值为2
field.set(i2, tmp); //int-->Object Integer.valueOf(tmp).intValue(), tmp的值是地址IntegerCache.cache[1+128],
}
}
javap -v App.class 查看App的字节码
自动封装
Integer a = 1; // Integer a = Ineger.valueOf(1);
valueOf(int i) i在-128到127之间,返回缓存中的值 return IntegerCache.cache[i + (-IntegerCache.low)]
所以Integer a=1,b=1时,a == b ,两个的内存地址是同一个。
上面运行结果:
a=2, b=2
解决:
Integer tmp = new Integer(i1.intValue());
得 a=2, b=1
知识点:
1.自动装箱和拆箱
2.Integer -128到127之间的缓存
3.反射,通过反射去修改private final 变量。
https://www.cnblogs.com/doStudying/p/7851254.html 这里列出了field.setInt()方法,跟上面的set方法的区别, 应该?是参数类型不一致,是否用到IntegerCache
http://www.docin.com/p-700305321.html 这里副本的值指向a,b的地址。用this可实现,但注意static方法里不能用this。
⑺ java中Integer在JDK1.6和JDK1.7中的区别
运行下面这段代码:
System.out.println(Integer.valueOf("127")==Integer.valueOf("127"));
System.out.println(Integer.valueOf("128")==Integer.valueOf("128"));
System.out.println(Integer.parseInt("128")==Integer.valueOf("128"));
JDK1.6输出结果:
false
false
true
JDk1.7输出结果:
true
false
true
JDK1.7版本开始,Integer有了静态缓存,这点注意一下。
⑻ int 和 Integer 的区别
int是java提供的8种原始数据类型之一,Java为每个原始类型提供了封装类,Integer是java为int提供的封装类。Integer 是一个类,是int的扩展,定义了很多的转换方法。另外,Integer提供了多个与整数相关的操作方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
⑼ Long和Integer分别在什么时候用
今天使用findbugs扫描项目后发现很多高危漏洞,其中非常常见的一个是比较两个Long或Integer时直接使用的==来比较。 其实这样是错误的。
因为Long与Ineger都是包装类型,是对象。 而不是普通类型long与int , 所以它们在比较时必须都应该用equals,或者先使用longValue()或intValue()方法来得到他们的基本类型的值然后使用==比较也是可以的。
但是有一种特殊情况, 其实Long与Integer都将 -128~127 这些对象缓存了。 可以看看Long类型源码里面有一个LongCache类,代码如下:
<pre class="java">private static class LongCache { private LongCache(){} static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for(int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } </pre>
先看看这个例子:
<pre class="java">public class Test05 { public static void main(String[] args) { Long a = 5L; Long b = 5L; System.out.println("a == b ? " + (a == b)); Long c = 129L; Long d = 129L; System.out.println("c == d ? " + (c == d)); } } </pre>
打印的结果是:
<pre class="css">a == b ? true c == d ? false </pre>
原因
首先来看看 Long a = 5L ; 它是如何将一个基本类型long包装成一个对象Long的 。
可以写一个测试类,然后反编译一下,看看java它是如何解析Long a = 5L这样一条命令的 。
测试类如下:
<pre class="java">public class Test06 { Long l = 3L; }</pre>
然后使用javap -verbose Test06 就能看到反编译的结果了, 下面是输出的部分:
<pre class="css">{ java.lang.Long l; public com.spring.test.Test06(); Code: Stack=3, Locals=1, Args_size=1 0: aload_0 1: invokespecial #10; //Method java/lang/Object."<init>":()V 4: aload_0 5: ldc2_w #12; //long 3l 8: invokestatic #14; //Method java/lang/Long.valueOf:(J)Ljava/lang/Long; 11: putfield #20; //Field l:Ljava/lang/Long; 14: return LineNumberTable: line 3: 0 line 5: 4 line 3: 14 LocalVariableTable: Start Length Slot Name Signature 0 15 0 this Lcom/spring/test/Test06; }</pre>
从Code中的8可以看出调用了Long的一个类方法Long.valueOf(Long) , 所以可以得到的结论是Long a = 5L实际上等于 Long a = Long.valueOf(5)
然后再看看Long.valueOf()方法是如何定义的:
<pre class="java"> public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); } </pre>
一目了然,会先判断基本类型的值如果在-128~127之间,就会直接从LongCache里面取出缓存的对象返回,否则就new一个新的Long对象返回 。
现在就不难理解Test05程序执行得到的结果了,因为a与b等于5,在-127~128之内,所以都是直接从LongCache里面返回的一个Long对象,所以他们在使用==比较的时候,就是相等的(对于对象类型来说,==比较的是两个对象的引用指向堆中的地址) ,而c与d等于129,不在-127~128之间,所以他们他们是分别new出来的两个新的Long对象,使用==来比较自然是不相等的了。
Long重写了equals方法:
<pre class="java"> public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; }</pre>
它是先通过.longValue()方法获取Long对象的基本类型long的值之后再做比较的。
所以对于Integer与Long的比较,最好是使用equals来比较才能确保得到我们想要的结果。
Integer与Long一样,这里就不举例了。
⑽ integer的默认缓存值是多少
Integer
变量存储为最接近编译环境的长度,例如在32位的编译环境下,Integer为32位,其范围为
-2^15
到
2^15-1
之间所以最大值是
2^15-1