Javaで整数加算を変更する方法は?
だから基本的に私はそれができるかどうか知りたいと思っていたのでいくつかの研究をしていました、そして私はこのコードを見つけました:
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
int n = 2+2;
System.out.println(n);
System.out.printf("%d",2 + 2);
}
}
なぜprintfステートメントが5を返すのか興味がありましたが、整数nを出力すると4が返されます。
回答
JavaはInteger、-128から127までの数値を表す256個のオブジェクトをキャッシュします。intがにボックス化されるIntegerと、その値が-128から127の間にあるInteger場合、キャッシュからのオブジェクトが使用されます。(詳細はこちら)。言語がこれをどのように行うかは、実装の詳細です。ご使用のバージョンのJavaでは、このキャッシュをの内部クラスのInteger、というInteger[]フィールドに格納しcacheます。他のバージョンのJavaでは、これが変更される可能性があるため、コードが破損する可能性があります。
コードの最初の部分は、整数キャッシュを取得し、インデックス132をインデックス133と同じに設定します。この配列は-128から始まるため、インデックス132は4の位置に対応し、インデックス133は次のようになります。ここで、5はです。これは、キャッシュ内の4を5に置き換えたことを意味します。
、、への引数printfは2 + 2、最初に4に評価されます。次に、ボックス化されてInteger。になります。これは、2番目のパラメーターとしてprintfのみを受け入れるためObjectです。4は-128から127の間にあるため、キャッシュが使用され、配列のインデックス132にアクセスしますInteger。これは、配列を変更しなかった場合、4があった場所であるためです。しかし、配列を変更したので、代わりに5を取得しました。
一方、を受け入れるオーバーロードがあるprintlnためprintln、4を出力しますint。したがって、ボクシングは発生しません。
ちなみに、「整数加算」を変更するのではなく、「整数ボクシング」を変更するだけです。