JavaFX保存扩展类变量
在我的evergrowing应用程序中,我有一个大约有50个变量的基类。还有10个从基类扩展而来的类。原因是这10个类有许多共同的变量,但也有一些是类本身独有的。现在我试图保存每个扩展类,所以我必须将基类变量与ClassX变量组合起来。这是一张照片: 在每个ClassX中,我都可以这样做:JavaFX保存扩展类变量,javafx,Javafx,在我的evergrowing应用程序中,我有一个大约有50个变量的基类。还有10个从基类扩展而来的类。原因是这10个类有许多共同的变量,但也有一些是类本身独有的。现在我试图保存每个扩展类,所以我必须将基类变量与ClassX变量组合起来。这是一张照片: 在每个ClassX中,我都可以这样做: super.saveData(); saveLocalData(); 这意味着我只需要在基类中提供一个saveData,但实际上需要多次重复saveLocalData-10 在每个类中,我只需使用以下命令即
super.saveData();
saveLocalData();
这意味着我只需要在基类中提供一个saveData,但实际上需要多次重复saveLocalData-10
在每个类中,我只需使用以下命令即可获得变量列表:
Field[] vars = DisplayField.class.getDeclaredFields();
我可以这样写变量名和值:
bw.write(f.getName() + "=" + f.get(this) + "\n");
我可以对所有ClassX类执行相同的操作,并构建这样的文本文件
然后我突然想到,如果我可以从FileIOClass获得每个ClassX的基类,那么我就可以得到一个由两部分组成的单个saveData。我可以做到:
for (DisplayField field : fieldList) // Iterate all the CLassX's
field.getClass().getSuperclass().getDeclaredMethod("saveDisplayField").invoke(bw);
然后我陷入了可怕的困境。有人能“解开”我吗?或者我只是找错地方了吗?你认为现在只需要基本类型,这是在限制自己,使你的应用程序无法扩展 你的问题有多种解决方案。你可以用e。G用于保存分层数据结构,它已经随Java提供 下面是一个简单的例子: BaseClass.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({
Class1.class,
Class2.class
})
@XmlRootElement(name = "Base")
public class BaseClass {
@XmlAttribute(name = "var1", required = true)
protected int var1;
@XmlAttribute(name = "var2", required = true)
protected int var2;
@XmlAttribute(name = "var3", required = true)
protected int var3;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3;
}
}
public class BaseClass {
@Persist
Integer var1;
@Persist
Integer var2;
@Persist
Integer var3;
}
Class1.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Class1")
public class Class1 extends BaseClass {
@XmlAttribute(name = "varX", required = false)
protected int varX;
@XmlAttribute(name = "varY", required = false)
protected int varY;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3 + ", varX=" + varX + ", varY=" + varY;
}
}
public class Class1 extends BaseClass {
@Persist
Integer varX;
@Persist
Integer varY;
}
Class2.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Class2")
public class Class2 extends BaseClass {
@XmlAttribute(name = "varA", required = false)
protected int varA;
@XmlAttribute(name = "varB", required = false)
protected int varB;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3 + ", varA=" + varA + ", varB=" + varB;
}
}
public class Class2 extends BaseClass {
@Persist
Integer varA;
@Persist
Integer varB;
}
Main.java
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class XmlExample {
public static void main(String[] args) {
// marshal base
BaseClass base = new BaseClass();
base.var1=1;
base.var2=2;
base.var3=3;
String baseXml = marshal( base);
// marshal class1
Class1 class1 = new Class1();
class1.var1=1;
class1.var2=2;
class1.var3=3;
class1.varX=10;
class1.varY=20;
String class1Xml = marshal( class1);
// marshal class2
Class2 class2 = new Class2();
class2.var1=1;
class2.var2=2;
class2.var3=3;
class2.varA=40;
class2.varB=50;
String class2Xml = marshal( class2);
// unmarshal base
unmarshal(baseXml);
// unmarshal class1
unmarshal(class1Xml);
// unmarshal class2
unmarshal(class2Xml);
System.exit(0);
}
public static String marshal( BaseClass base) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(BaseClass.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter stringWriter = new StringWriter();
jaxbMarshaller.marshal(base, stringWriter);
String xml = stringWriter.toString();
System.out.println("XML:\n" + xml);
return xml;
} catch (Exception e) {
throw new RuntimeException( e);
}
}
public static void unmarshal( String xml) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(BaseClass.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
StringReader stringReader = new StringReader(xml);
Object clazz = (Object) jaxbUnmarshaller.unmarshal(stringReader);
// create/cast here whatever class you need
if( clazz.getClass().isAssignableFrom( BaseClass.class)) {
System.out.println( "BaseClass:");
}
else if( clazz.getClass().isAssignableFrom( Class1.class)) {
System.out.println( "Class1:");
}
else if( clazz.getClass().isAssignableFrom( Class2.class)) {
System.out.println( "Class2:");
}
System.out.println( clazz + "\n");
} catch (Exception e) {
throw new RuntimeException( e);
}
}
}
控制台输出:
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Base var1="1" var2="2" var3="3"/>
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Class1 varX="10" varY="20" var1="1" var2="2" var3="3"/>
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Class2 varA="40" varB="50" var1="1" var2="2" var3="3"/>
BaseClass:
var1=1, var2=2, var3=3
Class1:
var1=1, var2=2, var3=3, varX=10, varY=20
Class2:
var1=1, var2=2, var3=3, varA=40, varB=50
Class: BaseClass
var1 = 1
var2 = 2
var3 = 3
Class: Class1
var1 = 4
var2 = 5
var3 = 6
varX = 10
varY = 20
Class: Class2
var1 = 7
var2 = 8
var3 = 9
varA = 30
varB = 40
您可以非常方便地序列化任何类型的对象,甚至是需要对象(如日期对象)的列表和格式
即使你不打算这样做,我也不会用反射来满足这种需求。而是在每个类中实现某种serializeToFile接口。除了我的第一个答案之外,这里还有另一种不同的解决方案,可以根据需要使用反射,因为这是您的问题。但正如我在另一个答案中所说的,你是在限制自己 我将创建一个自定义注释,这样您仍然可以在bean中执行您喜欢的任何操作 注释:Persist.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface Persist {
}
BaseClass.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({
Class1.class,
Class2.class
})
@XmlRootElement(name = "Base")
public class BaseClass {
@XmlAttribute(name = "var1", required = true)
protected int var1;
@XmlAttribute(name = "var2", required = true)
protected int var2;
@XmlAttribute(name = "var3", required = true)
protected int var3;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3;
}
}
public class BaseClass {
@Persist
Integer var1;
@Persist
Integer var2;
@Persist
Integer var3;
}
Class1.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Class1")
public class Class1 extends BaseClass {
@XmlAttribute(name = "varX", required = false)
protected int varX;
@XmlAttribute(name = "varY", required = false)
protected int varY;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3 + ", varX=" + varX + ", varY=" + varY;
}
}
public class Class1 extends BaseClass {
@Persist
Integer varX;
@Persist
Integer varY;
}
Class2.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Class2")
public class Class2 extends BaseClass {
@XmlAttribute(name = "varA", required = false)
protected int varA;
@XmlAttribute(name = "varB", required = false)
protected int varB;
public String toString() {
return "var1=" + var1 + ", " + "var2=" + var2 + ", " + "var3=" + var3 + ", varA=" + varA + ", varB=" + varB;
}
}
public class Class2 extends BaseClass {
@Persist
Integer varA;
@Persist
Integer varB;
}
这就是如何使用类并序列化它们的值:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
public class MainApp {
public static void log(BaseClass base) {
System.out.println( "\nClass: " + base.getClass().getName());
Class parent = base.getClass().getSuperclass();
while( parent != null) {
logFields( base, parent);
parent = parent.getSuperclass();
}
logFields( base, base.getClass());
}
public static void logFields(BaseClass obj, Class clazz) {
try {
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(Persist.class)) {
Annotation annotation = field.getAnnotation(Persist.class);
Persist test = (Persist) annotation;
System.out.println(field.getName() + " = " + field.get(obj));
}
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static void main(String[] args) throws Exception {
BaseClass base = new BaseClass();
base.var1 = 1;
base.var2 = 2;
base.var3 = 3;
log(base);
Class1 class1 = new Class1();
class1.var1 = 4;
class1.var2 = 5;
class1.var3 = 6;
class1.varX = 10;
class1.varY = 20;
log(class1);
Class2 class2 = new Class2();
class2.var1 = 7;
class2.var2 = 8;
class2.var3 = 9;
class2.varA = 30;
class2.varB = 40;
log(class2);
System.exit(0);
}
}
控制台输出:
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Base var1="1" var2="2" var3="3"/>
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Class1 varX="10" varY="20" var1="1" var2="2" var3="3"/>
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Class2 varA="40" varB="50" var1="1" var2="2" var3="3"/>
BaseClass:
var1=1, var2=2, var3=3
Class1:
var1=1, var2=2, var3=3, varX=10, varY=20
Class2:
var1=1, var2=2, var3=3, varA=40, varB=50
Class: BaseClass
var1 = 1
var2 = 2
var3 = 3
Class: Class1
var1 = 4
var2 = 5
var3 = 6
varX = 10
varY = 20
Class: Class2
var1 = 7
var2 = 8
var3 = 9
varA = 30
varB = 40
然后将数据序列化到您喜欢的任何类的文件中。这些变量是什么类型的?如果你需要保存e。G一份清单,你可能会犯严重的错误。关于你的要求没有足够的信息。从外观上看,我更愿意使用像e这样的注释框架。G保存数据。变量都是基本类型,例如double、int、boolean等。在我需要存储dropshadow参数的地方,我只存储“设置”,而不是dropshadow类-同样,只存储基本类型。所以没有什么棘手的存储。但不管变量的类型如何,基本问题仍然存在。哇,这对我来说是一个全新的世界。给我几小时,几天?消化所有这些,就像他们说的那样,我会随时通知你-谢谢你提供了如此详尽的例子。这是我欣赏StackOverflow的一件事——人们如何不遗余力地提供帮助。