2011-11-16 5 views
0

다음 프로그램은 SimpleKeyPair 클래스 내에서 선언 된 privateKey이라는 개인 필드를 액세스하고 수정합니다. 한번 살펴 보겠습니다. 위의 코드에서 Java에서 리플렉션을 사용하여 개인 클래스 멤버 액세스 및 수정


package mod; 

import java.lang.reflect.Field; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

final class SimpleKeyPair 
{ 
    private String privateKey = "Welcome SimpleKeyPair "; 
} 

final public class Main 
{ 
    public static void main(String[] args) 
    { 
     SimpleKeyPair keyPair = new SimpleKeyPair(); 
     Class c = keyPair.getClass(); 

     try 
     { 
      Field field = c.getDeclaredField("privateKey"); // gets the reflected object 
      field.setAccessible(true); 

      System.out.println("Value of privateKey: " + field.get(keyPair)); // displays “Welcome SimpleKeyPair" 

      field.set(keyPair, "Welcome PrivateMemberAccessTest"); // modifys the private member varaible 

      System.out.println("Value of privateKey: " + field.get(keyPair)); 
     } 
     catch (IllegalArgumentException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (IllegalAccessException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (NoSuchFieldException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     catch (SecurityException ex) 
     { 
      Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

는, 클래스 SimpleKeyPair 내에서 선언 민간 분야 privateKey 액세스 다음과 같은 문장을 통해 콘솔에 표시되고있다.

Field field = c.getDeclaredField("privateKey"); 
field.setAccessible(true); 
System.out.println("Value of privateKey: " + field.get(keyPair)); 

다음 문장을 통해 해당 필드가 수정되고, 그 필드의 새로운 값이 표시되고있다. 프로그램

field.set(keyPair, "Welcome PrivateMemberAccessTest"); 
System.out.println("Value of privateKey: " + field.get(keyPair)); 

실제 출력은 아래 것이다.

Value of privateKey: Welcome SimpleKeyPair 
Value of privateKey: Welcome PrivateMemberAccessTest 

는 자바 반사의 사용은 개인 리소스에 직접 액세스 할 수 있다는 것을 의미한다. 그렇다면 클래스 멤버를 private로 선언하는 목적 중 하나는 전 세계 외부에서 클래스 멤버를 숨기는 것이지만 개인을으로 선언하는 것은 안전하지 않습니다. 자바에서 리플렉션의 실제 사용은 무엇입니까?

답변

5

리플렉션을 통해 클래스의 개인 (패키지 및 보호 된) 범위 멤버에 대한 액세스를 허용하는 것이 맞습니다. 그러나 JavaDoc을 읽으면 요청 된 작업을 수행하기 전에 이러한 접근자를 가져 와서 호출하는 모든 메소드가 SecurityManager 검사를 수행한다는 것을 알 수 있습니다. 따라서 SecurityManger가있는 환경에서는 SecurityExceptions이 발생하여 작업이 실패합니다.

1

리플렉션을 사용하는 이유는 무엇입니까? 내성 검사, 동적 호출/해상도, 툴링 등을 할 수있는 능력

private의 실제 사용을 의미합니까? 의도를 선언하고 허용하지 않음 캐주얼 개인 회원의 악용 사례. ㅎ.

+0

이는 'SecurityManager'가 개인 회원의 * casual * 악용을 막을 수 있다는 것을 의미합니까? 그렇다면 인용하고 싶습니다. – meriton

+1

@meriton 클래스 파일 수정이 없다고 가정 할 때 보안 관리자에서 실행중인 경우 반영은 보안 관리자를 존중합니다. 원래의 질문은 그것을 언급하지 않았으므로 나는 또한하지 않았다. –

1

일반적으로 리플렉션은 메타 데이터 작업을 원할 때 유용합니다. 예를 들어, 많은 리플렉션 기능을 사용하는 최대 절전 모드와 같은 orm 프레임 워크가 있습니다.

관련 문제