先看下面方法:
public static void swap(Integer a , Integer b){
}
要求:交換a、b的值,并可以將互動后的結果回傳給呼叫方,就是說,比如在main方法有種如下呼叫代碼:
Integer a = 400;
Integer b = 200;
System.out.println("a="+a+",b="+b);
swap(a,b);
System.out.println("a="+a+",b="+b);
那么,期望的結果是:
400 ,200
200 ,400
先公布答案,
我們知道,如果將方法內部的區域變數實作互動,很簡單,如下3行輕松搞定,
int temp = b;
b=a;
a=temp;
但是,如果要求將互動結果回傳出來,就不奏效了,正確的姿勢是利用反射,即java.lang.reflect.Filed類,
public static void swap(Integer a , Integer b){ try { Field field = Integer.class.getDeclaredField("value"); field.setAccessible(true); int temp = b; field.set(b, a); field.set(a,new Integer(temp)); } catch (Exception e) { e.printStackTrace(); } }
好,接下來說問題,先看如下實作,
public static void swap(Integer a , Integer b){ try { Field field = Integer.class.getDeclaredField("value"); field.setAccessible(true); int temp = b; field.set(b, a); field.set(a,temp); } catch (Exception e) { e.printStackTrace(); } }
反復執行程式,發現當實參b>127 && b<-128時,可以正常交換;而一旦b∈[-128,127]時,這種交換并未改變a的值,
將field.set(a,temp);改成field.setInt(a,temp);之后,是可以解決的,
為什么呢?這跟swap方法中的區域變數temp是基本型別int有關,下面進一步闡釋,
我們通常利用反射給物件的屬性賦值時,都是用set方法,
那么,set與setInt在對于整型數字處理方面,有什么區別呢?
仔細推敲兩個方法的的javadoc可以得到結論,
setInt(Object obj, int i)
Sets the value of a field as an int on the specified object. This method is equivalent to set(obj, iObj), where iObj is a Integer object and iObj.intValue() == i.
這個方法等效于set(obj, iObj),在這個set方法第二個引數iObj的型別是Integer,并且((Integer)iObj).intValue()==setInt方法的第二個引數值i的情況下,
set(Object obj, Object value)
Sets the field represented by this Field object on the specified object argument to the specified new value. The new value is automatically unwrapped if the underlying field has a primitive type.
┢1) set方法的value引數是Object,要求用包裝型別(wrapped type),不能傳基本型別引數(primitive type),
┢2) setInt的第二個引數是int(即使傳的是Integer,也會拆箱為int),
上面的觀點1)并不妥當,比如上面的示例里,b的值在[-128,127]時是不行的,而這個范圍外的值是沒問題的,我們知道Integer類里的快取陣列cache的取值范圍就是[-128,127],不清楚這跟set的這種用法有什么關系,總之,用set方法時,value傳包裝型別是萬無一失的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/199880.html
標籤:其他
上一篇:使用redis制作一個簡單的防御模塊 抵御惡意http請求攻擊
下一篇:記錄一次用TCP協議傳檔案的探索
