serialVersionUIDの重複チェック
みんなね。
クラスをコピーしてもね。
serialVersionUIDを生成してくれないんだよ。
別に要件で必要じゃないんだけど、念のため全てのクラスにSerializable付けてるんだけなんだけどね。
コメントもちゃんと書いて?変えて?くれんし(涙
ということで、serialVersionUIDの重複チェックをするコードを書いてみた。
ついでに
・Serializableをimplementしてないクラス
・serialVersionUIDが未定義のクラス
も検出できるようにしてみる。
ClassViewerクラスはこちら。
(2009/02/04 id:hhelibexさんのコメントより、Serializableをimplementしているかどうかのチェックを、asSubclassメソッドからisAssignableFromメソッドに変更)
import java.io.Serializable; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class SerialVersionUidChecker implements Serializable { private static final long serialVersionUID = -2738454501799301164L; public SerialVersionUidChecker() { super(); } public static void main(String [] args) { new SerialVersionUidChecker().check("jp.co."); } public void check(String packageName) { ClassViewer viewer = new ClassViewer(); viewer.setup(); List classList = viewer.getAllClassList(); List errList = new ArrayList(); List noserialList = new ArrayList(); List undefIdList = new ArrayList(); Map idMap = new Hashtable(); for ( int i = 0 ; i < classList.size() ; i++ ) { String className = (String) classList.get(i); // 指定されたパッケージのみを対象とする if ((packageName != null) && (className.startsWith(packageName) == false)) { continue; } try { // クラスを取得 Class c = Class.forName(className); if (c.isInterface() == true) { continue; } // SerialVersionUIDを取得 String id = null; try { // Serializableをimplementしているかどうか(2009/02/04変更) //c.asSubclass(Serializable.class); if (Serializable.class.isAssignableFrom(c) == false) { System.out.println(className + ": Serializableがimplementされていません。"); noserialList.add(className); continue; } // 「private static final long serialVersionUID」を取得 Field f = c.getDeclaredField("serialVersionUID"); f.setAccessible(true); id = String.valueOf(f.get(null)); } catch (NoSuchFieldException noSuchFieldException) { System.out.println(className + ": SerialVersionUIDが未定義です。"); undefIdList.add(className); continue; } catch (SecurityException securityException) { System.out.println(className + ": SerialVersionUIDが未定義です。"); undefIdList.add(className); continue; } catch (IllegalAccessException illegalAccessException) { System.out.println(className + ": SerialVersionUIDが未定義です。"); undefIdList.add(className); continue; } // SerialVersionUIDのマップの有無を確認 if (idMap.get(id) == null) { idMap.put(id, new ArrayList()); } else { System.out.println(className + ": SerialVersionUIDが重複しています。"); } // リストにクラス名を追加 List list = (List) idMap.get(id); list.add(className); } catch (ClassNotFoundException classNotFoundException) { System.out.println(className + ": ClassNotFoundExceptionです。"); errList.add(className); } catch (NoClassDefFoundError noClassDefFoundError) { System.out.println(className + ": NoClassDefFoundErrorです。"); errList.add(className); } catch (UnsatisfiedLinkError unsatisfiedLinkError) { System.out.println(className + ": UnsatisfiedLinkErrorです。"); errList.add(className); } } System.out.println("\n【エラーとなったクラス】"); for ( int i = 0 ; i < errList.size() ; i++ ) { System.out.println((String) errList.get(i)); } System.out.println("\n【Serializableがimplementされていないクラス】"); for ( int i = 0 ; i < noserialList.size() ; i++ ) { System.out.println((String) noserialList.get(i)); } System.out.println("\n【SerialVersionUIDが未定義のクラス】"); for ( int i = 0 ; i < undefIdList.size() ; i++ ) { System.out.println((String) undefIdList.get(i)); } System.out.println("\n【SerialVersionUIDが重複しているクラス】"); Iterator ite = idMap.entrySet().iterator(); while (ite.hasNext()) { Entry entry = (Entry) ite.next(); String id = (String) entry.getKey(); List list = (List) idMap.get(id); if (list.size() > 1) { System.out.println("[" + id + "]"); for ( int i = 0 ; i < list.size() ; i++ ) { System.out.println((String) list.get(i)); } } } } }