Java 将配置 class 保存到可编辑文件中
Java save a configuration class into an editable file
您好,我想保存一个 Java class,其中包含我的应用程序的一些配置
示例:
class MyConfig {
public int a= 0;
public boolean b= true;
}
而且我希望这个文件可以被用户编辑,乍一看 JSONSerializer 对于一个简单的案例来说是可以的。
但我想要更多...例如,将来我想从我的 class 添加/删除字段...它仍然有效吗?
(如果添加了一个字段,我希望在加载包含旧 class 的文件时使用默认值......)
不知道我说清楚没有...
但是如果我可以添加
public String c= "hello";
然后加载文件(不包含字段 c 的值)。
谢谢!
编辑:
这就是我正在尝试的:
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");
}
}
}
当然我可以保存我的测试class...
public class TestClass implements Serializable {
public boolean a= true;
//public int i= 1;
}
但我无法加载 :( 失败:
Exception in thread "main" java.lang.ClassCastException: Cannot cast
java.lang.String to boolean at java.lang.Class.cast(Class.java:3369)
at
net.sf.aldrigo.propertiesSerializer.PropertiesSerializer.load(PropertiesSerializer.java:55)
at
net.sf.aldrigo.propertiesSerializer.MainTest.main(MainTest.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497) at
com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
要么查看 SimpleXml or just use java.util.Properties 并通过 Reflection 自己滚动。
您好,我想保存一个 Java class,其中包含我的应用程序的一些配置 示例:
class MyConfig {
public int a= 0;
public boolean b= true;
}
而且我希望这个文件可以被用户编辑,乍一看 JSONSerializer 对于一个简单的案例来说是可以的。 但我想要更多...例如,将来我想从我的 class 添加/删除字段...它仍然有效吗? (如果添加了一个字段,我希望在加载包含旧 class 的文件时使用默认值......)
不知道我说清楚没有... 但是如果我可以添加
public String c= "hello";
然后加载文件(不包含字段 c 的值)。 谢谢!
编辑: 这就是我正在尝试的:
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");
}
}
}
当然我可以保存我的测试class...
public class TestClass implements Serializable {
public boolean a= true;
//public int i= 1;
}
但我无法加载 :( 失败:
Exception in thread "main" java.lang.ClassCastException: Cannot cast java.lang.String to boolean at java.lang.Class.cast(Class.java:3369) at net.sf.aldrigo.propertiesSerializer.PropertiesSerializer.load(PropertiesSerializer.java:55) at net.sf.aldrigo.propertiesSerializer.MainTest.main(MainTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
要么查看 SimpleXml or just use java.util.Properties 并通过 Reflection 自己滚动。