2016-03-27 7 views
-1

編集可能なファイルに設定クラスを保存します。Javaは、私は私のアプリ 例えば、いくつかの設定が含まれているJavaクラスを保存したいこんにちは

class MyConfig { 
public int a= 0; 
public boolean b= true; 
} 

そして、私は、このファイルはでは、ユーザーが編集可能にしますJSONSerializerはシンプルなケースでOKです。 しかし、私は何かもっと欲しいです...例えば、将来私はクラスからフィールドを追加/削除したいと思います。 (フィールドが追加されている場合、古いクラスを含むファイルをロードするときにデフォルト値を使用したいと考えています)

私は明確かどうかわかりません... たとえば場合、私は

public String c= "hello"; 

を追加して(フィールドcの値が含まれていない)ファイルを読み込むことができます。 ありがとうございました!

EDIT:...

public class PropertiesSerializer<T> { 
    private final Class clDef; 
    private T obj; 

    public T get(){ return obj; } 

    public PropertiesSerializer(Class cl){ //uhm... 
     if (cl == null) throw new NullPointerException(); 
     clDef= cl; 
    } 

    public void init() throws InstantiationException { 
     Constructor[] ctors = clDef.getDeclaredConstructors(); 
     Constructor ctor = null; 
     for (int i = 0; i < ctors.length; i++) { 
      ctor = ctors[i]; 
      if (ctor.getGenericParameterTypes().length == 0) 
       break; 
     } 

     ctor.setAccessible(true); 
     try { 
      obj = (T) ctor.newInstance(); 
     } catch (IllegalAccessException e) { 
      throw new InstantiationException(e.getMessage()); 
     } catch (InvocationTargetException e) { 
      throw new InstantiationException(e.getMessage()); 
     } 
    } 

    public void load(String filename) throws IOException, InstantiationException { 
     File fl= new File(filename); 
     Properties props= new Properties(); 
     try (FileReader reader= new FileReader(fl)) { 
      props.load(reader); 
     } 

     init(); 
     for(Field fd: clDef.getFields()){ 
      try { 
       Object valobj= props.getProperty(fd.getName()); 
       obj.getClass().getField(fd.getName()).set(obj, fd.getType().cast(valobj)); //uhm... 
      } catch (IllegalAccessException e) { 
       e.printStackTrace(); 
      } catch (NoSuchFieldException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void save(String filename) throws InvalidStateException, IllegalAccessException, IOException { 
     if(obj == null) throw new InvalidStateException("init wasn't called!"); 

     File fl= new File(filename); 
     Properties prop= new Properties(); 
     for(Field fd: clDef.getFields()){ 
      prop.setProperty(fd.getName(), String.valueOf(fd.get(obj))); //uhm... 
     } 

     try(FileWriter writer = new FileWriter(fl)) { 
      prop.store(writer, "PropertiesSerializer"); 
     } 
    } 
} 

もちろん、私は私のテストクラスを保存することができます

public class TestClass implements Serializable { 
    public boolean a= true; 
    //public int i= 1; 
} 

が、私はそれをロードすることはできません:(: これはI'amがしようとするものです失敗:

スレッド "main"での例外java.lang.ClassCastException:キャストできません java.lang.String to boolean to jav でa.lang.Class.cast(Class.java:3369) net.sf.aldrigo.propertiesSerializer.MainTest.mainでnet.sf.aldrigo.propertiesSerializer.PropertiesSerializer.load(PropertiesSerializer.java:55) ( : sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.javaで sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) でsun.reflect.NativeMethodAccessorImpl.invoke0(ネイティブメソッド)でMainTest.java:17) 43) com.intellij.rt.execution.application.AppMain.mainでjava.lang.reflect.Method.invoke(Method.java:497)で (AppMain.java:144)

+1

これまでに何を試しましたか? –

+0

[java.util.Properties](https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html)と 'storeToXML()'を参照してください。 – markspace

+0

あなたが望むことはできますが、実行時にクラスをコンパイルするたびに実行されます。実行形式でJavaクラスをコンパイルすると、それほど良いアイデアではありません。 –

答えて

0

SimpleXmlをご覧になるか、またはjava.util.Propertiesを使用して、Reflection経由で自分自身をロールしてください。

+0

'java.util.Propertiesを使用し、Reflection経由で自分自身をロールバックしてください。 私のコードを読んでください...しかし、私は仕事を得ることができません。毎回キャストするのが好きではありません...またはクラスをforeachに書く...私の解決策は普遍的なものになりたかった... しかし、私はSimpleXml – Raffa505

+0

Reflectionをもっと深く見てみたら、それを書いたら、「各クラスのために」書く必要はありません。ジェネリックスを使用している場合。私は心からSimpleXMLをお勧めします。これは、C#で提供されるXMLシリアル化と同じ容易さを提供します。巨大な勝利。唯一のことは、モデルに後で余分なフィールドを追加する場合は、適切なタグを追加してシリアル化するかどうかをマークする必要があります。しかし、名前が示すように、それは "シンプル"です:) – ManoDestra

関連する問題