2016-02-16 56 views
1
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。調用這些方法時是否可以避免類型轉換?有沒有什麼辦法可以避免使用泛型參數調用方法時的類型轉換?

+0

你實際上實現了一個橋接方法 - 編譯器在處理類型參數時在幕後執行的方法。 :) –

+0

你不需要'dataType'參數。你可以從'element.getClass()'中獲得它。我懷疑'setValue()'方法應該是通用的:相反,您應該提供所有必需的重載。 – EJP

+0

@Tom,這是我的錯誤,但我不希望別人專注於這個程序的每一行。我只是把原型,以得到我的答案..again謝謝你.. – 027

回答

1

可以讓事情更清潔:

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); 
} 
+0

您的答案的最後一段回答了我的問題..謝謝.. – 027

1

解決此問題的一種方法是使用Factory Pattern,該工具正好創建用於需要創建對象而無需爲創建的對象指定確切類的情況。

希望這會有所幫助。

+0

這是如何回答有關避免類型轉換的問題? –

+0

確實應該詳細說明,因爲它需要一些重構。但是我們需要使用覆蓋而不是重載來使多態在Java中工作。 – pdem

+0

使用工廠是避免直接投射的一種方法,以及 - 下面的答案如何顯示 - 顯然不是唯一的方法。 – Diferdin

2

如果您希望該方法是通用的,則需要轉換。但是,您可以重載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"); 
} 
+0

這個問題背後的想法是什麼,我想鞏固一個地方的東西,所以有意義的是,我只想創建一個方法,可以接受這兩種參數類型,並可以調用更多的方法.. – 027

1

問題是該類沒有可以在方法調用中知道的參數類型。你可以參數化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方法內部進行投射。

相關問題