簡體   English   中英

有什么方法可以避免在使用通用參數調用方法時避免類型轉換?

[英]Is there any way with which I can avoid type casting while calling method with generic parameter?

public static void main(String[] args) {

    GenericTest genericTest = new GenericTest();

    genericTest.setValue(new BigDecimal("10"),BigDecimal.class);
    genericTest.setValue(new Date(0), Date.class);

    }

    public <T> void setValue(T element, Class<T> dataType)
    {
        if(dataType == Date.class){
            checkDate((Date)element);
        }
        else if(dataType == BigDecimal.class){
            checkBigDecimal((BigDecimal)element);
        }
    }

    public void checkDate(Date localDate)
    {
        System.out.println("This is Date metho, Caller has casted T to Date");
    }

    public void checkBigDecimal(BigDecimal localBigDecimal)
    {
        System.out.println("This is BigDecimal method, Caller has casted T to BigDecimal");

    }

在這里,當調用checkDate和CheckBigDecimal方法時,我分別將類型轉換為Date和BigDecimal。 可以在調用這些方法時避免類型轉換嗎?

如果要使方法通用,則需要強制類型轉換。 但是,您可以只重載setValue方法。 像這樣:

public static void main(String[] args) {

    GenericTest genericTest = new GenericTest();

    genericTest.setValue(new BigDecimal("10"));
    genericTest.setValue(new Date(0));

}

public void setValue(BigDecimal element) {
    checkBigDecimal(element);
}

public void setValue(Date element) {
    checkDate(element);
}

public void checkDate(Date localDate) {
    System.out.println("This is Date metho, Caller has casted T to Date");
}

public void checkBigDecimal(BigDecimal localBigDecimal) {
    System.out.println("This is BigDecimal method, Caller has casted T to BigDecimal");
}

解決此問題的一種方法是使用Factory Pattern ,它是為需要創建對象而不必為創建的對象指定確切類的情況而專門創建的。

希望這可以幫助。

問題在於該類沒有可在方法調用之間獲知的參數類型。 您可以參數化GenericTest類:

public class GenericTest<T> {
    private T value;

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return this.value;
    }
}

最好在類范圍內綁定參數類型,因為您有依賴該類型相同的跨方法調用。 換句話說,不允許在同一實例上調用setValue(String)和setValue(Date)。 上面的代碼應防止此類調用。

有了上面的內容,您的類甚至不需要checkDate / checkBigDecimal方法(假設它們旨在進行驗證):

GenericTest<Date> dateGeneric = new GenericTest<>();
dateGeneric.setValue(new Date()); //The compiler will prevent any other type to be passed to this method

如果仍然需要checkXYZ方法(例如,您正在驗證通用輸入),則無法避免強制轉換,因此使用通用是不合適的。 您可以簡單地使用一個Object字段並將其強制轉換到checkXYZ方法內部,作為驗證的一部分。

您可以使事情變得更干凈:

public class genericTest {
    public static void main(String[] args) {
        genericTest genericTest = new genericTest();
        genericTest.setValue(new BigDecimal("10".toString()));
        genericTest.setValue(new Date(0));

    }

    public <T> void setValue(T element) {
        if (element instanceof Date) {
            check((Date) element);
        }

        if (element instanceof BigDecimal) {
            check((BigDecimal) element);
        }
    }

    public void check(Date localDate) {
        System.out.println("This is Date metho, Caller has casted T to Date " + localDate);
    }

    public void check(BigDecimal localBigDecimal) {
        System.out.println("This is BigDecimal method, Caller has casted T to BigDecimal: " + localBigDecimal);
    }
}

但是,這仍然不能解決您的問題,因為仍然需要強制轉換。 問題是您希望在運行時動態應用方法重載。 Java不會這樣做-編譯器將嘗試將您的代碼解析為特定的(重載)方法調用,並且類似以下內容的操作將失敗,因為它無法確定要應用哪個(如果有) check()

public <T> void setValue(T element) {
    check(element);
}

暫無
暫無

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

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