만족
[Android] 'int java.math.RoundingMode.ordinal()' on a null object reference 본문
[Android] 'int java.math.RoundingMode.ordinal()' on a null object reference
FrontEnd/Android Satisfaction 2021. 6. 23. 21:14
위의 Object를 read한 후, 그것을 write하고 다시 read하려고 할 때 발생한 예외이다.
신기한 것은 처음 read했을 때는 문제가 발생하지 않고,
그 데이터를 write한 다음, 다시 read했을때만 오류가 발생한다.
W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.math.RoundingMode.ordinal()' on a null object reference at java.text.DecimalFormat.convertRoundingMode(DecimalFormat.java:4129) at java.text.DecimalFormat.readObject(DecimalFormat.java:4397) at java.lang.reflect.Method.invoke(Native Method) at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1066) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2013) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1899) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1412) W/System.err: at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2114) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2038) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1899) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1412)
스택을 따라가보니 다음 코드에서 NullPointerException이 발생하는 원인이 생기는 것으로 추정된다.
(DecimalFormat.java: 4397)
fields.get()부분에서 Null을 반환한 후, setRoundingMode에서 전달된 값이 null일 경우 NPE를 발생시킨다.
그렇다면 write에서 예외가 발생해 쓰기 작업 자체에 문제가 생긴 것인가? 하고 디버깅을 해 봤지만,
write에서는 예외가 발생하지 않는다.
검색해봐도 명쾌한 해결법은 나오지 않아서, 우회하는 방법으로 문제를 해결했다.
해결법1
사실 나의 경우에는 Open_SearchDateRange라는 클래스를 다른 클래스에서 포함하기 때문에 Serializable하게 두었을 뿐,
start, end값을 제외한 ~~format들은 은 불변값이기 때문에 굳이 Serializable할 필요가 없다.
따라서 static키워드를 사용해, 다른 클래스의 수정을 유발하지 않고
Serialize/Deserialize의 대상이 되지 않게 수정했다.
해결법 2
Format Template이 가변값이라면 골치아파진다.
그래도 약간의 꼼수를 통해 수정해보자.
어차피 우리가 필요한 값은 formatter 그 자체가 아니라,
format시 어떤 템플릿을 사용할 거냐? 이기 때문에
템플릿을 스트링으로 따로 빼서 Serialize/Deserialize에는 문제가 없게 변경해 주고,
이런식으로 메소드를 거쳐 사용하도록 하면 문제가 해결된다.
해결법3
해결법2을 조금 더 응용한 방법이다.
//...
public String dateFormatTemplate= "yyyy-MM-dd HH:mm";
private transit SimpleDateFormat dateFormat= null;
//...
public Open_SearchDateRange(){
dateFormat= new SimpleDateFormat(dateFormatTemplate);
}
//...
}
transit 키워드를 사용해, SimpleDateFormat타입의 Object를 Serialize 대상에서 제외한다.
그렇게 하면 Serialize 작업 시 transit 키워드가 붙은 멤버 값은 무조건 null로 다뤄진다.
(null값은 아예 Serialize/Deserialize 대상이 아니기 때문에, Serializable하지 않은 타입도 올 수 있다)
String dateFormatTemplate는 Serialize/Deserialize에 문제가 없으므로,
Deserialize가 완료된 후 기본 생성자에서 dateFormat을 할당해주는 방식으로 문제를 회피할 수 있다.
'FrontEnd > Android' 카테고리의 다른 글
[Android] 웹뷰 앱 제출 시 주의사항 (개발자 프로그램 정책 위반) (0) | 2021.07.16 |
---|---|
[Android] TextView에 부분 폰트 스타일 적용하기 (0) | 2021.07.05 |
[Android] 이미지에 색상(tint)을 적용하는 방법 (0) | 2021.06.19 |
[Android] SQLite Database (0) | 2021.06.14 |
[Android] CorotineScope (0) | 2021.06.14 |