Java에서 private
액세스 수정자는 클래스 외부에서 볼 수 없기 때문에 안전한 것으로 간주합니다. 그러면 외부 세계도 그 방법에 대해 알지 못합니다.
하지만 Java 리플렉션이이 규칙을 깨는 데 사용할 수 있다고 생각했습니다. 다음 경우를 고려하십시오.
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
이제 다른 클래스에서 정보를 얻을 것입니다.
public class BreakPrivacy{
public static void main(String[] args) throws Exception {
ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
method.setAccessible(true);
Object result = method.invoke(protectedPrivacy);
System.out.println(result.toString());
}
}
지금은 위와 같은 일을하기 위해서는 메소드 이름을 알아야하므로 여전히 private 메소드가 안전하다고 생각했습니다. 그러나 다른 누군가가 작성한 private 메서드를 포함하는 클래스는 가시성이 없습니다.
그러나 코드 줄 아래부터 내 요점이 무효화됩니다.
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
이제 여기 method[]
에는 위의 작업에 필요한 모든 것이 포함됩니다. 제 질문은 Java 리플렉션을 사용하여 이러한 종류의 일을 피할 수있는 방법이 있습니까?
내 질문을 명확히하기 위해 Java Documentation 에서 몇 가지 요점을 인용했습니다 .
액세스 수준 선택에 대한 팁 :
다른 프로그래머가 클래스를 사용하는 경우 오용으로 인한 오류가 발생하지 않도록해야합니다. 액세스 수준은이를 수행하는 데 도움이 될 수 있습니다. 특정 구성원에게 적합한 가장 제한적인 액세스 수준을 사용합니다. 정당한 이유가없는 한 비공개로 사용하세요.
답변
“안전하다”는 의미에 따라 다릅니다. 이런 종류의 일을 허용하는 보안 관리자와 함께 실행하는 경우 예, 모든 종류의 불쾌한 일을 반성 할 수 있습니다. 그러나 그런 종류의 환경에서 라이브러리는 어쨌든 메소드를 공개하도록 수정 될 수 있습니다.
액세스 제어는 이와 같은 환경에서 효과적으로 “자문”입니다. 코드가 멋지게 재생되는 것을 효과적으로 신뢰하고 있습니다. 실행중인 코드를 신뢰할 수 없다면 더 제한적인 보안 관리자를 사용해야합니다.
답변
액세스 수정자는 보안과 관련이 없습니다. 실제로 액세스 수정자를 보안의 역방향으로 볼 수 있습니다. 이는 데이터 나 알고리즘을 보호하는 것이 아니라 데이터와 알고리즘에 대해 알아야하는 요구 사항으로부터 사람들을 보호하는 것입니다. 이것이 기본 수정자가 package 인 이유입니다. 패키지에서 작업중인 경우 이미 알아야 할 것입니다.
데이터 및 코드 방법에 대한 지식과 함께 사용시기와 방법을 알 책임이 있습니다. 누군가가 그것에 대해 알아내는 것을 막기 위해 inIt 메서드에 비공개를 두지 않습니다. (a) foo 다음에 호출하고 bar = 3.1415 및 (b) 인 경우에만 호출한다는 것을 알지 못하기 때문입니다. 그들이 그것에 대해 아는 것이 좋지 않기 때문입니다.
액세스 modifers이 간단한 문구로 요약 할 수있다 “TMI, 친구, 내가 그렇게 알 필요하지 않았다.”
답변
‘안전하다’는 말은 개인 메서드를 호출하여 개체에 해를 끼치 지 않기 위해 API를 사용하는 귀하 또는 다른 개발자를 보호하는 것입니다. 그러나 당신이나 그들이 정말로이 메서드를 호출해야한다면, 리플렉션으로 할 수 있습니다.
답변
문제는 누구 로부터 저장 하려고 하는가입니다. 내 생각에, 당신의 코드의 그러한 클라이언트는 여기서 손실을 입는 것이다.
private
위 클래스 의 구성원에 액세스하려고 시도하는 코드 (귀하 또는 다른 사람이 작성한) 는 본질적으로 자체 무덤을 파고 있습니다. private
회원은 공개 API 의 일부를 만들지 않으며 예고없이 변경 될 수 있습니다. 클라이언트가 위와 같은 방식으로 이러한 개인 구성원 중 하나를 사용하는 경우 개인 구성원이 수정 된 API의 최신 버전으로 업그레이드하면 중단됩니다.
답변
시설에는 책임이 따릅니다. 이 일이 당신의있다 없다 할, 당신이 일 수 할 수 있지만 하지 말아야 할.
Private modifier는 가장 제한된 방식으로 제공 / 사용됩니다. 클래스 외부에서 보이지 않아야하는 멤버는 비공개로 정의됩니다. 그러나 이것은 우리가 볼 수 있듯이 Reflection으로 깨질 수 있습니다. 그러나 이것은 당신이 개인적으로 사용해서는 안된다는 것을 의미하지는 않습니다. 그것은 당신이 사물을 현명하게 또는 건설적인 방식으로 (반성처럼) 사용하는 것에 관한 것입니다.
답변
API의 클라이언트 프로그래머를 신뢰한다고 가정 할 때 다른 방법은 특정 기능을 사용하는 것이 얼마나 ‘안전’한지입니다.
공개적으로 사용 가능한 함수는 코드에 명확하고 잘 문서화되고 거의 변경되지 않는 인터페이스를 제공해야합니다. 개인 기능은 구현 세부 사항으로 간주 될 수 있으며 시간이 지남에 따라 변경 될 수 있으므로 직접 사용하는 것이 안전하지 않습니다.
클라이언트 프로그래머가 이러한 추상화를 회피하기 위해 자신의 방식을 벗어나면 자신이 무엇을하고 있는지 알고 있다고 선언하는 것입니다. 더 중요한 것은 지원되지 않으며 향후 버전의 코드 작업이 중단 될 수 있음을 이해하고 있다는 것입니다.
답변
private
보안을위한 것이 아니라 코드를 깨끗하게 유지하고 실수를 방지하는 것입니다. 이를 통해 사용자 는 다른 모듈의 모든 세부 사항에 대해 걱정할 필요없이 코드 (및 개발 방법)를 모듈화 할 수 있습니다.
코드를 공개하면 사람들이 코드가 어떻게 작동하는지 알아낼 수 있습니다. 결국 컴퓨터에서 코드를 실행하려는 경우 논리를 “숨길”방법이 없습니다. 바이너리로 컴파일하는 것조차 난독 화 수준입니다.
따라서 다른 사람이 호출하지 못하도록하는 특별한 작업을 수행하도록 API를 설정할 수있는 방법이 없습니다. 웹 API의 경우 제어 할 메서드를 서버 측에 둘 수 있습니다.