在我不断增长的应用程序中,我有一个包含大约50个变量的BaseClass。还有10个其他类从BaseClass扩展。原因是这10个类有许多共同的变量,但也有一些属于类本身。现在我试图保存每个扩展类,所以我必须将BaseClass变量与ClassX变量结合起来。这是一张图片:
我可以在每个ClassX中使用类似的东西:
super.saveData();
saveLocalData();
这意味着我只需要在BaseClass中提供一个saveData,但实际上很多重复的saveLocalData() - 10。
在每个班级中,我都可以通过以下方式获得变量列表:
Field[] vars = DisplayField.class.getDeclaredFields();
我可以像这样编写变量名和值:
bw.write(f.getName() + "=" + f.get(this) + "\n");
我可以为所有ClassX类做同样的事情并构建一个类似的文本文件。
然后让我感到震惊的是,如果我可以从FileIOClass到达每个ClassX的BaseClass,我可以只有一个saveData()(由两部分组成)。我可以得到:
for (DisplayField field : fieldList) // Iterate all the CLassX's
field.getClass().getSuperclass().getDeclaredMethod("saveDisplayField").invoke(bw);
然后我被卡住了。任何人都可以解开'我或者我只是在这里咆哮错误的树?
答案 0 :(得分:0)
您正在限制自己,并认为您只需要基本类型(目前),使您的应用程序无法扩展。
您的问题有各种解决方案。你可以。 G。使用JAXB来保存分层数据结构,它已经附带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;
}
}
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;
}
}
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;
}
}
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
您可以使用这种非常方便的序列化任何类型的对象,甚至是需要像日期对象这样的对象的列表和格式。
即使你不打算这样做,我也绝不会将反射用于那种要求。而是在每个类中实现某种“serializeToFile”接口。
答案 1 :(得分:0)
除了我的第一个答案,这是另一种不同的解决方案,一种使用反射(如你所愿),因为这是你的问题。但正如我在另一个答案中所说的那样,你要限制自己。
我创建了一个自定义注释,这样你仍然可以在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
public class BaseClass {
@Persist
Integer var1;
@Persist
Integer var2;
@Persist
Integer var3;
}
Class1.java
public class Class1 extends BaseClass {
@Persist
Integer varX;
@Persist
Integer varY;
}
Class2.java
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);
}
}
控制台输出:
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
然后将数据序列化为您喜欢的任何类别的文件。