JAXB使用setter方法生成了一个类,该方法将抽象类作为参数:
setAppointmentDate(AvailableDates)
我理解我无法实例化抽象类,所以为了创建一个AvailableDates
对象传递给方法,我创建了一个AvailableDates
的匿名子类(同时实例化)它)。这有效,并给我预期的结果。但是,为了创建匿名子类,我已经硬编码了抽象类的名称:
AvailableDates anonymous = new AvailableDates() {};
我现在需要使这个动态化,因为类AvailableDates
的名称将作为参数传入。我已开始
为此使用反射:
String className = "AvailableDates";
Class abstractClass = Class.forName(className);
我现在需要从中创建一个匿名类,但无法看到我的能力。我能看到的最好的 是:
Object dates = abstractClass.newInstance();
这显然会失败,因为您无法创建抽象类的实例。我看到Is it possible to create an anonymous class while using reflection?如果我理解正确,听起来我不能使用匿名类的反射。任何人都可以添加更多建议 - 是否有另一种方法可以解决这个问题,尤其是在JAXB环境中?
答案 0 :(得分:1)
JAXB将生成一个抽象类,以对应XML Schema中的抽象复杂类型。在下面的示例中,复杂类型contactInfo
将对应于名为ContactInfo
的抽象类,生成的类Customer
也将具有此类型的属性。
<xs:schema
version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com/foo"
targetNamespace="http://www.example.com/foo">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="contactInfo" type="contactInfo" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="contactInfo" abstract="true">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="address">
<xs:complexContent>
<xs:extension base="contactInfo">
<xs:sequence>
<xs:element name="street" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="phoneNumber">
<xs:complexContent>
<xs:extension base="contactInfo">
<xs:attribute name="number" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
对于此类型的属性,将值设置为具体子类之一。
Address address = new Address();
customer.setContactInfo(address);
或者
PhoneNumber phoneNumber = new PhoneNumber();
customer.setContactInfo(phoneNumber);
如何确定使用哪个具体子类?
实际上并不是一种自动执行此操作的方法,您需要根据您尝试表示的数据进行特定选择。在上面的示例中,如果您希望通过邮件联系客户,则设置Address
的实例,否则您设置PhoneNumber
的实例。
我确实尝试使用其中一个具体的子类,它就像你一样 说过。缺点是这些具体的子类并不是真的 与我使用的setter方法有关。我能想到的一个例子 是setAppointmentDate(StaffLeaveDates)。这里StaffLeaveDates延伸 AvailableDates作为一个具体的子类,但实际上并没有什么可做的 预约日期但仍然有效。你觉得这样吗? 我能做的最好吗?我只是觉得它看起来很混乱。
JAXB将使您能够创建与XML Schema兼容的任何XML文档。就它而言,你告诉它(通过XML Schema)允许任何扩展AvailableDates
的类型,以便它会愉快地接受StaffLeaveDates
。您可以尝试更改XML Schema,使其更具限制性(参见下面的示例)。
XML架构
下面是XML Schema的更新版本,它引入了一个名为contactInfo
的{{1}}新子类型,我不希望将其用作{{1}上的值} emailAddress
上的属性。因此,我更改了contactInfo
,以便在customer
和customer
之间进行选择。
address
生成的模型
现在我的phoneNumber
课程可以抓住<xs:schema
version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com/foo"
targetNamespace="http://www.example.com/foo">
<xs:element name="customer">
<xs:complexType>
<xs:choice>
<xs:element name="address" type="address"/>
<xs:element name="phoneNumber" type="phoneNumber"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="contactInfo" abstract="true">
<xs:sequence/>
</xs:complexType>
<xs:complexType name="address">
<xs:complexContent>
<xs:extension base="contactInfo">
<xs:sequence>
<xs:element name="street" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="phoneNumber">
<xs:complexContent>
<xs:extension base="contactInfo">
<xs:attribute name="number" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="emailAddress">
<xs:complexContent>
<xs:extension base="contactInfo">
<xs:attribute name="address" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
或Customer
(或两者都不幸),但不能Address
。无论什么属性为null都不会被编组为XML。
PhoneNumber