次のコードは、Java7を使用しprivate final char value[]
てStringクラスのフィールドに値を設定しようとします。
package test;
import java.lang.reflect.Field;
public final class Test
{
static
{
try
{
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set("Hello World", value.get("1234567890"));
}
catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e)
{
System.out.println(e.toString());
}
}
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
そしてそれはコンソールに静かに表示さ1234567890
れ、それについては疑問の余地はありません。
次のようにJava6を使用して同じことを行おうとすると、
package test;
import java.lang.reflect.Field;
public final class Test
{
static
{
try
{
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set("Hello World", value.get("1234567890"));
}
catch (IllegalArgumentException e)
{
System.out.println(e.toString());
}
catch (IllegalAccessException e)
{
System.out.println(e.toString());
}
catch (NoSuchFieldException e)
{
System.out.println(e.toString());
}
catch (SecurityException e)
{
System.out.println(e.toString());
}
}
public static void main(String[] args)
{
System.out.println("Hello World");
}
}
次の例外がスローされます。
スレッド「メイン」の例外java.lang.ArrayIndexOutOfBoundsException
value.get("1234567890")
このステートメントの長さがvalue.set("Hello World", value.get("1234567890"));
文字列以上の場合に機能しますHello World
例えば、
次のステートメントの場合(前のコードスニペットのように)
value.set("Hello World", value.get("1234567890"));
次のようなものに置き換えられます
value.set("Hello World", value.get("12345678901"));
では、メソッドの2番目のパラメーターの長さが最初のパラメーターよりも短いのに、なぜこれがJava 6で機能しないのでしょうか(または、もっと低くなる可能性がありますが、試しませんでした)。set()
ところで、このようにリフレクションを使ってプライベートフィールドを扱うことは、まったく推奨されておらず、最悪であることを理解できます。