簡體   English   中英

Java反射與抽象類

[英]Java Reflection with Abstract classes

JAXB已經使用setter方法生成了一個類,該方法將抽象類作為其參數:

setAppointmentDate(AvailableDates)

我知道我無法實例化抽象類,因此為了創建一個AvailableDates對象傳遞給該方法,我創建了AvailableDates的匿名子類(同時實例化了它)。 這有效,並給了我預期的結果。 但是,為了創建匿名子類,我對抽象類的名稱進行了硬編碼:

AvailableDates anonymous = new AvailableDates() {};

我現在需要使此動態,因為類AvailableDates的名稱將作為參數傳遞。 我開始為此使用反射:

String className = "AvailableDates";
Class abstractClass = Class.forName(className);

現在,我需要從中創建一個匿名類,但是看不到我該怎么做。 我能看到的最好的是:

Object dates = abstractClass.newInstance();

顯然,這將失敗,因為您無法創建抽象類的實例。 我看到可以在使用反射時創建匿名類嗎? 如果我理解正確的話,聽起來我不能對匿名類使用反射。 任何人都可以添加更多建議-特別是在JAXB的情況下,還有其他解決方法嗎?

抽象類從哪里來?

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實例。


UPDATE

我確實嘗試過使用其中一個具體的子類,它的工作方式就像您說的那樣。 缺點是這些具體的子類與我使用的setter方法沒有真正的關系。 我能想到的一個例子是setAppointmentDate(StaffLeaveDates)。 在這里,StaffLeaveDates將AvailableDates擴展為一個具體的子類,但實際上與約會日期沒有任何關系,但它仍然有效。 您認為這是我能做的最好的嗎? 我只是在想這可能會令人困惑。

JAXB將使您能夠創建與XML Schema兼容的任何XML文檔。 就其而言,您告訴它(通過XML Schema)允許任何擴展AvailableDates類型,以便它可以愉快地接受StaffLeaveDates 您可以嘗試更改XML模式,以使其更具限制性(請參見下面的示例)。

XML模式

下面是XML Schema的更新版本,它引入了一個新的contactInfo子類型,稱為emailAddress ,我不想將它用作customercontactInfo屬性的值。 因此,我已更改customer以在addressphoneNumber之間進行選擇。

<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類可以保留一個AddressPhoneNumber (或不幸的是兩個),但是不能保留EmailAddress 屬性為null的任何屬性都不會編組為XML。

@XmlRootElement(name = "customer")
public class Customer {

    protected Address address;
    protected PhoneNumber phoneNumber;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM