⑴ 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