Android アプリケーション クラス ローダーは、public static
(前述のクラスが定義されているものとは異なる) 別のパッケージからでもパッケージ プライベート クラスのフィールドへの参照を反射的に取得できるようですが、たとえば Sun JDK クラスローダーはそうではありません。
より具体的には、次のクラス定義が与えられます。
package org.example.a
class PackagePrivateClass {
public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator();
}
そして、別のパッケージの次のコード:
package org.example.b
public class TestClass {
public void testMethod() {
final Class classRef = Class.forName("org.example.a.PackagePrivateClass");
final Field creatorFieldRef = classRef.getField("CREATOR");
creatorFieldRef.get(null); // throws here (unless on Android)
}
}
Sun JVM で実行するIllegalAccessException
と、最後の行で次のようにスローされます。
java.lang.IllegalAccessException: Class org.example.b.TestClass can not access a member of class org.example.a.PackagePrivateClass with modifiers "public static final"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
...
ただし、Android デバイス (5.1 Lollipop FWIW) で実行すると、スローせずに実行され、creatorFieldRef.get(null)
実際にはフィールドへの有効な参照が返されCREATOR
ます。
私の質問は次のとおりです。なぜそうなのですか?Androidクラスローダーのバグか機能ですか?? (または、該当する場合、私の例で何が間違っていましたか?)