あるパッケージにクラスAがあるとしましょう:
package test; public class A { private int x = 33; public void test(){ System.out.println(x); } }
ご覧のとおり、フィールドxは保護されており、 sunのドックによると、このフィールドはサブクラスA、テストパッケージ、または他のパッケージでも表示されません。 したがって、test()メソッドは常に数値33を返すと信じるあらゆる理由があります。さらに、コードでこの仮定を使用し、それに何らかのロジックを結び付けることができます。
次に、他のパッケージにクラスがあります(ただし、同じJVM内にあります)。
package access; public class X { public void getAccess() throws Exception{ A a = new A(); Field x = a.getClass().getDeclaredField("x"); x.setAccessible(true); x.setInt(a, x.getInt(a)+1); System.out.print("protected field: "); a.test(); } }
以上です。 A.xフィールドのカプセル化と不変性に関するすべての仮定は払拭されます。 A. test()メソッドは数値34を返すようになりました(そして、何らかのロジックをそれに結び付けた場合、コードは現在正しく動作しそうにありません)。 そして、PLOの3つの戒めの1つであるカプセル化に違反しているように見えることさえあります。
その後、このパッケージを詳しく調べてみると、特別なSecurityManagerクラスがセキュリティとアクセスを維持する役割を担っており、それを実行するとすべてが適切に配置されることがわかりました。 クラスAに静的初期化子を追加する場合:
public class A { static{ if(System.getSecurityManager()==null) System.setSecurityManager(new SecurityManager()); }
前の例で判明したそのかすかな耳は通りません。 T.ch. すべてが順調で、JavaはまだOO言語です:)この投稿を書いた唯一のことは、すべてのジャビストに警告することです (これはアクションのシグナルではありません。
開発者、BDI!
実行時にSecurityManagerがない場合、誰でもクラスにクロールして、何でも変更できます!