2013-04-26 3 views
6

나는 반사 아주 새로운 오전 I는 역시 같은 있습니다
AccessibleObject 클래스의 setAccessible 메서드 뒤에 boolean 매개 변수가있는 이유는 무엇입니까?

public void setAccessible(boolean flag) throws SecurityException 

이 방법은 모든 필드 나 메소드의 새로운 접근을 나타내는 boolen 매개 변수 플래그를 가지고 있습니다. 우리는 클래스 외부에서 클래스의 private 방법에 액세스하려고하는 경우 예를 들어
우리는 getDeclaredMethod를 사용하는 방법을 가져오고 true로 접근성을 설정, 그래서 같이 호출 할 수 있습니다 : 시나리오에서 이제 method.setAccessible(true);
method.setAccessible(false);을 사용해야합니다. 예를 들어 public 메소드가 있고 접근성을 false로 설정할 때 사용할 수 있습니다. 그러나 그 필요성은 무엇입니까? 내 이해가 명확한가요?
method.setAccessible(false)의 아무 소용이 우리가 같은 방법 서명을 변경할 수있는 경우 :

public void setAccessible() throws SecurityException 
+1

당신은 코드의 프로그래머가 ** 의도하지 않은 상태에서 반사 아래 코드를 떠나고 싶어하지 않습니다 ** . 너? 검사를 위해 반사를 _unlock_ 코드 조각에 사용했습니다. 나중에 _unlocked_로 남기시겠습니까? –

+0

예. 너의 요점을 알아 냈어. –

+0

내 질문을 개선 할 수 있도록 의견을 말하면 좋겠다. –

답변

5

시나리오 : 당신이 개인 필드에서 보호를 제거 Field.setAccessible(true),이 그것을 읽고 Field.setAccessible(false).

와 함께 원래의 상태로 필드를 반환으로
+9

이렇게 할 수는 있지만 어떤 클라이언트도 언제든지 필드 인스턴스를 얻을 수 있기 때문에 액세스 가능성을 false로 다시 설정하여 효과가 없다. 필드를 사용하려면, setAccessible (true)를 다시 사용합니다. 또한 setAccessible은 필드의 접근성을 비 반사 방식으로 영구 변경하지 않으므로 비 반사 방식으로 필드를 사용하는 클라이언트로부터 보호 할 수 있습니다. – mickeymoon

+0

동의하지만이 작업을 항상 수행해야합니다. 아무도 여기서 '거짓'값을 전달하지 않을 것입니다. 그렇다면 왜 추가 코드를 작성해야합니까? – Dennis

14

아마도 평생 동안 setAccessible(false)을 수행하지 않았을 것입니다. 이는 setAccessible이 멤버의 가시성을 영구적으로 변경하지 않기 때문입니다. method.setAccessible(true)과 같은 번호로 method 인스턴스를 호출 할 수 있습니다. 원본 소스의 메소드가 개인 인 경우에도 마찬가지입니다.

예를 들어이 사항을 고려하십시오

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

답변 해 주셔서 감사합니다. –

+0

당신은 환영합니다 :) – 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)); 

} 

}