2015-10-11 6 views
10

Androidアプリケーションクラスローダーは、パッケージJpクラスローダー(例えば前述のクラスが定義されているもの)とは別のパッケージからでもパッケージプライベートクラスのpublic staticフィールドへの参照を反射的に取得することができます't。Androidクラスローダーは、別のパッケージのパッケージプライベートクラスの公開フィールドへのアクセスを許可するのはなぜですか?

より具体的に

は、次のクラス定義を与える:

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) 
    } 
} 

日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 Lollipo p FWIW)スローすることなく実行され、creatorFieldRef.get(null)は実際にCREATORフィールドへの有効な参照を返します。

私の質問です:それはなぜですか?それはAndroidクラスローダーのバグか機能ですか? (?または、該当する場合、私は私の例では間違って何を手に入れた)

答えて

2

は、このcommitで修正されましたアンドロイドランタイムのバグだと思わ:

メソッドへのアクセスチェックを追加し、フィールドリフレクション。

このコミットの前に、制限なしでリフレクトすることでフィールドにアクセスしたり、the value of final fieldsと設定することもできました。

アクセスチェックnowは、ランタイム機能ValidateFieldAccessValidateAccessで実装されています。

+0

コミットコードは実際には別のパッケージの非公開クラスのフィールドへのアクセスを拒否するようですが、コミットはART固有のバグに対処し、Lollipopのオンに含まれていますKitKat ARTで再現)、私の質問のサンプルコードはAndroid VM、Dalvik、(最新の)ARTには投げられません。あなたはそれがバグかもしれないと私は確信していたので、私は[AOSPへの問題](https://code.google.com/p/android/issues/detail?id=191727)を提出し、意図的か否か。ありがとう。 – desseim

関連する問題