의 힘에 대해 더 많이 배울수록 java.lang.reflect.AccessibleObject.setAccessible
그것이 무엇을 할 수 있는지에 대해 더욱 놀랐습니다. 이것은 질문에 대한 내 대답에서 수정되었습니다 ( 반영을 사용하여 단위 테스트를 위해 정적 최종 File.separatorChar 변경 ).
import java.lang.reflect.*;
public class EverythingIsTrue {
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}
}
정말 터무니없는 일을 할 수 있습니다.
public class UltimateAnswerToEverything {
static Integer[] ultimateAnswer() {
Integer[] ret = new Integer[256];
java.util.Arrays.fill(ret, 42);
return ret;
}
public static void main(String args[]) throws Exception {
EverythingIsTrue.setFinalStatic(
Class.forName("java.lang.Integer$IntegerCache")
.getDeclaredField("cache"),
ultimateAnswer()
);
System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42"
}
}
아마도 API 설계자는 남용이 얼마나 될 setAccessible
수 있는지 알고 있지만이를 제공하기 위해 합법적 인 용도가 있다는 것을 인정했을 것입니다. 그래서 내 질문은 다음과 같습니다.
- 진정으로 합법적 인 용도는
setAccessible
무엇입니까?- Java가 애초에 이러한 필요성을 갖지 않도록 설계되었을 수 있습니까?
- 그러한 설계의 부정적인 결과 (있는 경우)는 무엇입니까?
setAccessible
합법적 인 용도로만 제한 할 수 있습니까 ?- 그것은 통해서만
SecurityManager
입니까?- 어떻게 작동합니까? 화이트리스트 / 블랙리스트, 세분성 등?
- 응용 프로그램에서 구성해야하는 것이 일반적입니까?
- 구성에
setAccessible
관계없이 내 클래스를 증명할 수 있도록 작성할 수 있습니까SecurityManager
?- 아니면 구성을 관리하는 사람의 자비입니까?
- 그것은 통해서만
한 가지 더 중요한 질문은 다음과 같습니다.이 문제에 대해 걱정해야합니까 ???
내 수업 중 누구도 강제적 인 개인 정보 보호와 같은 모습을 보이지 않습니다. 싱글 톤 패턴 (장점에 대한 의문을 제쳐두고)은 이제 시행이 불가능합니다. 위의 스 니펫에서 볼 수 있듯이 Java 기본 작동 방식에 대한 몇 가지 기본적인 가정조차도 보장되지 않습니다.
이 문제는 진짜가 아닌가 ???
좋아, 난 그냥 확인 : 덕분에 setAccessible
, 자바 문자열은 하지 불변.
import java.lang.reflect.*;
public class MutableStrings {
static void mutate(String s) throws Exception {
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set(s, s.toUpperCase().toCharArray());
}
public static void main(String args[]) throws Exception {
final String s = "Hello world!";
System.out.println(s); // "Hello world!"
mutate(s);
System.out.println(s); // "HELLO WORLD!"
}
}
이것이 큰 관심사라고 생각하는 유일한 사람입니까?