Java反射与抽象类

时间:2014-12-19 09:38:39

标签: java reflection jaxb abstract-class anonymous-class

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环境中?

1 个答案:

答案 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,以便在customercustomer之间进行选择。

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