
最近、The Daily WTF
は 、Reflectionが同僚の良い血を台無しにするのにどのように役立つかについて
書いています。
次のコードがあるとしましょう:
public class ConstantHolder { public static final Integer THE_ANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING = 42; }
そして
public class TestBoxingVulnerability { public static void main(String[] args) { int theAnswer = ConstantHolder.THE_ANSWER_TO_LIFE_THE_UNIVERSE_AND_EVERYTHING; System.out.println(theAnswer == 42); } }
明らかに
trueが出力されます。 ただし、プロジェクトには、状況を逆方向に変更できるようなコードが含まれている場合があります。 猫の下はそのようなコードの例です。
ConstantHolderクラス(またはロードされる別のクラス)に次のコードを追加するだけで十分です。
static {
その後、プログラムの出力は
false変わり
false 。
なぜそう
ご覧のとおり、定数は
Integer型で、テストクラスのローカル変数は
int型です。
int Integerに割り当てようとすると、
valueフィールドは
Integer -aから読み取られ、リフレクションを使用して別の値を割り当てるため、ユーザーが期待するものは読み取られません。
あなたが推測できるように、コードのエントリが他のどこかにある場合
Integer someInteger = 42;
そして、この
someIntegerが使用され、その値は
boxing / anboxing中のキャッシュにより同じ9000に
なります。 つまり、
Integer.valueOf(anInt)は、特定の
anInt値に対して同じオブジェクトを
anIntます。
これに対抗する方法はなく、ありそうもない。 注意して、同僚を怒らせないでください:)