Fieldを利用して設定ファイルの記述を簡易化
http://d.hatena.ne.jp/alpha_neet/20101001/1285945730
前回のenumを使った簡易化なんですが今見るとかなりひどいです。おまえenum使いたかっただけちゃうんかと自分に思わずツッコミそうです。
今度はFieldを使ったやつに書き換えてみました。今回は型指定しているので変換が楽だと思います。
import java.util.Properties; import java.util.Enumeration; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.InvocationTargetException; class PropertiesLoader { private final String filename; /** * save */ public void save() { this.save(this.filename); } public void save(String filename) { try { Properties p = new Properties(); // 前回のPropertiesファイル読み込み File f = new File(this.filename); if(f.exists()) { p.load(new FileInputStream(this.filename)); } // 保存するpropertiesファイルの読み込む f = new File(filename); if(!f.exists()) f.createNewFile(); Class<?> clazz = this.getClass(); Field[] fields = clazz.getDeclaredFields(); for(Field val: fields) { try { val.setAccessible(true); if(val.get(this) == null) continue; /** * インナークラスで使用した場合親オブジェクトへの * 参照を持ってしまうのでfinal修飾子は外す * ほかにも単純にfinalは使わないようにする仕様 */ if(Modifier.isFinal(val.getModifiers())) continue; p.setProperty(val.getName(), val.get(this).toString()); p.store(new FileOutputStream(filename), null); //} catch(IllegalAccessException e2) { } } catch(Exception e2) { e2.printStackTrace(); } } } catch(IOException e) { e.printStackTrace(); } } /** * initialize */ public PropertiesLoader() { this("config.properties"); } public PropertiesLoader(String filename) { this.filename = filename; try { // Propertiesファイル読み込み File f = new File(filename); if(!f.exists()) f.createNewFile(); Properties p = new Properties(); p.load(new FileInputStream(filename)); // Propertiesファイルのkeyを一つずつ取得 Enumeration e = p.propertyNames(); while(e.hasMoreElements()) { try { String key = e.nextElement().toString(); String data = p.getProperty(key); if(data==null) continue; // keyと同じ名前のfieldがあるか検索 Class<?> clazz = this.getClass(); Field val = clazz.getDeclaredField(key); val.setAccessible(true); Class<?> type = val.getType(); // 同じ名前があれば型ごとにキャスト if(type == String.class) { val.set(this,data); } else if(type == int.class) { val.set(this,Integer.valueOf(data)); // int以外のプリミティブ型の場合 } else if(type.isPrimitive()) { String name = type.getName(); // 先頭だけ大文字にする name = name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); name = "java.lang."+name; Method valueOf = Class.forName(name). getMethod("valueOf", String.class); val.set(this,valueOf.invoke(null, data)); // それ以外の場合は(Integer, Floatなど)は // valueOfがあればinvokeする } else { Method valueOf=type.getMethod("valueOf", String.class); val.set(this,valueOf.invoke(null, data)); } } catch(NoSuchFieldException e2) { continue; } // catch(ClassNotFoundException e2) { } // catch(InvocationTargetException e2) { } // catch(NoSuchMethodException e2) { } // catch(IllegalAccessException e2) { } catch(Exception e2) { e2.printStackTrace(); } } } catch(IOException e) { e.printStackTrace(); } } } class ConfigTest { class MyConfig extends PropertiesLoader { String FILE_PATH; boolean WINDOW_MAXIMIZED; int WINDOW_X; int WINDOW_Y; int WINDOW_W; int WINDOW_H; Integer In; float fl; Float Fl; } void p(Object o) { System.out.println(o); } ConfigTest() { MyConfig $ = new MyConfig(); p($.FILE_PATH); p($.WINDOW_X); p($.WINDOW_Y); p($.WINDOW_W); p($.WINDOW_H); p($.WINDOW_MAXIMIZED); p($.In); p($.fl); p($.Fl); $.FILE_PATH = "aiueo"; $.WINDOW_X = 10; $.WINDOW_Y = 20; $.WINDOW_W = 30; $.WINDOW_H = 40; $.WINDOW_MAXIMIZED = true; $.In = 30; $.fl = 5.0f; $.Fl = 10.0f; $.save(); } public static void main(String[] args) { new ConfigTest(); }}