리플렉션에 대해 공부하던 중 갑자기 궁금한 점이 생겼습니다. final 키워드가 붙은 곳도 변경이 가능하다는 점인데요
이를 실제로 변경하게 되면 어떤 결과가 나올까요?
https://stackoverflow.com/questions/3301635/change-private-static-final-field-using-java-reflection
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"
System.out.println();
System.out.println(false);//false
System.out.println(Boolean.FALSE);//true
}
}
정말 당혹스러운 결과입니다
false라고 하는 저 부분을 리플렉션을 통해서 변경해 버리면 false를 출력했다고 생각했음에도, true를 반환하는 것을 볼 수 있습니다
2번째 값은 false를
3번재 값은 true를 출력하게 됩니다
Boolean 클래스의 내부 값을 변경할 수 있어서 생긴 일인데요
format 함수의 경우에 Object 타입의 args를 받습니다. 따라서 false는 Boolean.FALSE로 오토박싱이 일어납니다
public String toString() {
return value ? "true" : "false";
}
그 결과 출력에서 사용되는 true, false 의 결과가 우리 생각대로 나오지 않은 것이죠
2번째 값은 그대로 원시값을 사용했기에, 변경이 되지 않은 모습이고
3번째 값은 변경된 객체를 참조하고 있기에 문제가 발생한 모습입니다
그 결과 어떤 문제가 발생하느냐?
System.out.println(Boolean.FALSE.equals(true));
이게 true 인 결과가 나옵니다
혼란을 없애기 위해서 리플렉션으로 final 변수를 수정하는 것은 지양합시다
'Java' 카테고리의 다른 글
자바 버전 올릴 수 있을까? (0) | 2024.02.22 |
---|---|
우리 프로젝트에서 java 17을 사용하게 된 이유 (0) | 2023.07.02 |
Stream collect 알아보기 (0) | 2023.03.13 |
Java 멀티 쓰레드 아는체하기 (1) | 2023.03.05 |
Java Exception 알아보기 (0) | 2023.02.27 |