Skip to main content

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;
    }
};

이렇게 수정하면 되고, 경고를 무시해도 실행에는 영향은 없다. 그냥 직렬화 호환성 보장이 안 된다는 컴파일러 경고라서 직렬화를 전혀 쓰지 않는 프로그램이면 그냥 놔둬도 상관없다.