2013-04-26 10 views
6

Ben Yansıma çok yeni ve bir şüphe gibi vardır:
SetAccessible AccessibleObject sınıfının arkasındaki nedenin bir boole parametresi var mı?

public void setAccessible(boolean flag) throws SecurityException 

Bu yöntem herhangi bir alan ya da yöntemlerin yeni erişilebilirlik belirten bir boolen parametre bayrağı vardır. Sınıfta dışından sınıfın bir private yöntemi erişmeye çalıştığınızda ise bir örnek için
sonra getDeclaredMethod kullanarak yöntemini alıp true olarak erişilebilirliği ayarlamak, bu yüzden gibi çağrılabilir: senaryosu Şimdi method.setAccessible(true);
method.setAccessible(false);'u kullanmalıyız, bir örnek için public yöntemi kullanıldığında kullanılabilir ve erişilebilirliği yanlış olarak ayarladık. Ama bunun ihtiyacı nedir? Anlayışım açık mı?
method.setAccessible(false) hiçbir faydası o zaman böyle bir yöntem imzası değiştirebilir varsa:

public void setAccessible() throws SecurityException 
+1

Sen kod programcı ** niyetinde değildi bir durumda yansıması altında kod bırakmak istemiyoruz ** . Yapıyor musun ? Muayene için bir parça kod olan _unlock_'a yansıma kullandın, sonradan _unlocked_ bırakmak ister misin? –

+0

Yup. Senin noktanı aldın. –

+0

Downvoater Lütfen sorularımı geliştirebilmemiz için bir yorum yazabilir misiniz? –

cevap

5

Senaryo: Özel bir alandan koruma kaldırıldı Field.setAccessible(true), okumak ve Field.setAccessible(false).

ile tekrar eski haline alanı döndürmedi ile
+9

bunu yapabilirsiniz, ancak herhangi bir istemci herhangi bir zaman bir alan örneği alabildiği için tekrar false olarak ayarlayarak erişimi engelleyemediğiniz için bu hiçbir etki yaratmaz ve alanı kullanmak için setAccessible (true) değerini tekrar kullanın. Ayrıca setAccessible, alanın erişilebilirliğini kalıcı olarak değiştirmez veya yansıma yapmayan bir şekilde değiştirmez, böylece alanı REFLECTION olmayan bir şekilde kullanan istemcilerden koruyabilirsiniz .. – mickeymoon

+0

Anlaştık, ama her zaman bunu yapmak zorundayız. Kimse buradaki “yanlış” değeri geçmeyecek. Öyleyse neden fazladan bir kod yazmak zorunda kalıyorsun? – Dennis

14

Muhtemelen hayatınızda asla setAccessible(false) yapmazsınız. Bunun nedeni, setAccessible öğesinin görünürlüğünü kalıcı olarak değiştirmemesidir. method.setAccessible(true) gibi bir şeye sahip olduğunuzda, orijinal kaynaktaki yöntem özel olsa bile numaralımethod örneğinde sonraki aramaları yapmanıza izin verilir.

Örneğin bu düşünün:

A.java 
******* 
public class A 
{ 
    private void fun(){ 
    .... 
    } 
} 

B.java 
*********** 
public class B{ 

    public void someMeth(){ 
     Class clz = A.class; 
     String funMethod = "fun"; 

     Method method = clz.getDeclaredMethod(funMethod); 
     method.setAccessible(true); 

     method.invoke(); //You can do this, perfectly legal; 

     /** but you cannot do this(below), because fun method's visibilty has been 
      turned on public only for the method instance obtained above **/ 

     new A().fun(); //wrong, compilation error 

     /**now you may want to re-switch the visibility to of fun() on method 
      instance to private so you can use the below line**/ 

     method.setAccessible(false); 

     /** but doing so doesn't make much effect **/ 

    } 

}

+0

Cevabınız için teşekkür ederiz. –

+0

rica ederim :) – mickeymoon

0
//create class PrivateVarTest { private abc =5; and private getA() {sop()}} 


import java.lang.reflect.Field; 
import java.lang.reflect.Method; 

public class PrivateVariableAcc { 

public static void main(String[] args) throws Exception { 
    PrivateVarTest myClass = new PrivateVarTest(); 

    Field field1 = myClass.getClass().getDeclaredField("a"); 

    field1.setAccessible(true); 

    System.out.println("This is access the private field-" 
      + field1.get(myClass)); 

    Method mm = myClass.getClass().getDeclaredMethod("getA"); 

    mm.setAccessible(true); 
    System.out.println("This is calling the private method-" 
      + mm.invoke(myClass, null)); 

} 

} 
İlgili konular