The serializable class does not declare a static final serialVersionUID field of type long 해결법
import java.util.LinkedHashMap;
import java.util.Map;
class Solution {
public int solution(int cacheSize, String[] cities) {
if (cacheSize == 0) return cities.length * 5; // 캐시 없으먄 모두 miss
int time = 0;
// accessOrder = true
// 이렇게 하면 최근에 접근한 순서대로 자동 정렬
LinkedHashMap<String, String> cache = new LinkedHashMap<>(cacheSize, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize; // 캐시 크기 초과하면 자동으로 가장 오래된 것 삭제
}
};
for (String city : cities) {
city = city.toLowerCase();
if (cache.containsKey(city)) {
time += 1; // hit
} else {
time += 5; // miss
}
cache.put(city, city); // 접근시 자동으로 최근 순서 갱신
}
return time;
}
}
The serializable class does not declare a static final serialVersionUID field of type long
클래스가 Serializable인데 UID 안 넣은 경우 → serialVersionUID 추가하면 됨
public class MyCache implements Serializable {
private static final long serialVersionUID = 1L;
private LinkedHashMap<String, String> cache;
public MyCache(int cacheSize) {
cache = new LinkedHashMap<>(cacheSize, 0.75f, true);
}
}
직렬화 쓸 일이 없다면 implements Serializable 제거하기
익명 내부클래스(anonymous inner class) → serialVersionUID 추가하면 됨
내 코드에서 LinkedHashMap을 그냥 쓰는 게 아니라 {...} 블럭으로 removeEldestEntry를 오버라이드한 부분 때문이다.
LinkedHashMap<String, String> cache = new LinkedHashMap<>(cacheSize, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize;
}
};
- LinkedHashMap 은 원래 Serializable을 구현하고 있고 serialVersionUID도 정의되어 있다.
- 그런데 익명 클래스를 만들면, 새로운 클래스가 정의된다.
- 이름 없는 클래스지만 사실상 Class MyLinkedHashMap extends LinkedHashMap {...} 같은게 생긴 셈이다.
- 새 클래스도 Serializable을 상속받게 되는데, serialVersionUID를 선언하지 않아서 경고가 뜨는 것
LinkedHashMap<String, String> cache = new LinkedHashMap<>(cacheSize, 0.75f, true) {
// SerialVersionUID에서 1은 long 타입의 1
// 소문자 1도 되지만 숫자 1이랑 헷갈려서 보통 대문자 L을 쓴다고 함
// 여기서 serialVersionUID는 직렬화 할 때 버전번호 역할 하는 값
// 아무 숫자 long 타입이나 넣으면 되지만, 관례적으로 1L를 많이 씀
// 그냥 버전1 이라고 선언한 정도로 기능적인 의미는 없음
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > cacheSize;
}
};
이렇게 수정하면 되고, 경고를 무시해도 실행에는 영향은 없다. 그냥 직렬화 호환성 보장이 안 된다는 컴파일러 경고라서 직렬화를 전혀 쓰지 않는 프로그램이면 그냥 놔둬도 상관없다.