[英]JAVA : How to return value in generic function
我正在用 JAVA 泛型概念測試一些小實踐。
我嘗試從通用函數返回一個 List,但 compile 不允許我這樣做。
檢查下面的代碼:
package com.test.generic.method;
import java.util.ArrayList;
import java.util.List;
public class Sample_3<T> {
public <T> List<T> testReturn(T t) {
List<T> list = new ArrayList<T> ();
list.add(t);
return list;
}
public static void main(String a[]) {
String s = "Gunjan";
Sample_3 sample = new Sample_3<String>();
List<String> list =(List<String>) sample.testReturn(sample);
for(String ab : list){
System.out.println(ab);
}
}
}
它給出了
ClassCastException
。
如何從泛型函數返回列表? 為什么 JAVA 增加了這樣的編譯時特性?
謝謝,甘詹。
泛型The
目的是讓您自由指定。 因此,您可以執行以下操作:
public List<T> testReturn(T t){
List<T> list = new ArrayList<T>();
list.add(t);
return list;
}
這將允許你做例如
List<String> a = testReturn("A");
List<Integer> b = testReturn(1);
您的代碼的問題在於您的方法的意圖並不是真正通用 - 該方法被編寫為返回一個 List<String>。 代碼中的<T>
實際上不會影響任何事情。
在回答您的進一步問題時 - 您已經寫了以下內容:
public class Sample_3 {
public <T> List<T> testReturn(T t) {
List<T> list = new ArrayList<T> ();
list.add(t);
return list;
}
public static void main(String a[]) {
String s = "Gunjan";
// this is wrong - the Sample_3 class is not generic. It does not get a generic type parameter.
Sample_3 sample = new Sample_3<String>();
// this is also wrong. Since the method is generic the "T" you get is the same as the "T" that
// goes into the method. Here your String output type does not match the input type of the method,
// which you've set here as a Sample_3 object
List<String> list =(List<String>) sample.testReturn(sample);
}
您的通用參數 T 設置可以變化的類型。 您可以在方法級別(如上所述)或在類級別執行此操作:
public class Sample_3<T> {
public List<T> getList(){ ... }
}
例如
List<Integer> l = new Sample_3<Integer>().getList();
List<String> s = new Sample_3<String>().getList();
List<Calendar> c = new Sample_3<Calendar>().getList();
您需要進行簽名:
public List<String> testReturn()
當您在方法聲明中使用<T>
,它會根據傳入的參數之一告訴編譯器您要在方法中使用泛型類型。因為您沒有傳入任何類型為T
參數,所以編譯器無法解析T
到一個類型。
您正在指定 T 列表的返回類型,但返回字符串列表。 快速解決方法是:
public List<String> testReturn(){
List<String> list = new ArrayList<String>();
// add stuff to list;
return list;
}
實際上,泛型的目的是允許您對類(即 Sample)進行泛化,以便您可以創建它的新實例,但要指定它為每個實例處理的對象類型。 Java 在編譯時檢查這些泛型。 以 List 為例 - 沒有泛型,它不關心我放入列表中的對象 - 這意味着我可能會在沒有收到警告的情況下放入 Double ,並且我不知道它包含什么樣的對象時我調用 get()。 我們可以編寫僅限於特定對象的新類或 List 實現——例如,StringList 只能接受字符串——但這會很耗時並且可能難以維護。 相反,Java 泛型允許我們將特定 List 的輸入/輸出限制為特定類(以及該類的任何實現)——例如 List 只接受並返回字符串。
例如生成樣本:
public class Sample<T> {
public List<T> makeEmptyList(){
return new ArrayList<T>();
}
}
您還可以在靜態方法中指定泛型,但必須將泛型類型傳入 - 作為對象或類引用:
public static <T> List<T> makeAndAddToList(T t){
List<T> list = new ArrayList<T>();
list.add(t);
return list;
}
public static <T> List<T> makeEmptyList(Class<T> clazz){
return new ArrayList<T>();
}
在您的情況下,尚不清楚您的 Sample 類是否應該限制為處理字符串和列表,或者是否應該使其通用。
有關更多信息,請查看Java 教程。
我認為要問的第一個問題是,當您在方法中顯式創建List<String>
時,為什么要聲明返回List<T>
的方法? 該示例不會通過使用泛型為您購買任何東西。 您是否正在嘗試解決其他一些情況?
只是為了給您一個快速的教訓,當 Java 編譯您的類時,泛型將從字節碼中刪除。 所以,在你的編輯器中最初可能是這樣的:
public <T> List<T> testReturn(){
}
public List<String> testReturn2(){
}
看起來像這樣一旦編譯為字節碼:
public List testReturn(){
}
public List testReturn2(){
}
這稱為類型擦除。 泛型的目的是允許編譯時參數檢查,從而在運行時刪除異常。 將產生運行時錯誤的非通用代碼示例如下:
List list = new ArrayList();
list.add("Hello World");
list.add(Integer.valueOf(42));
for (int i = 0; i < list.size(); i++) {
String str = (String) list.get(i);
}
列表中的字符串和整數是不兼容的類型。 泛型禁止這種不安全的訪問/數據輸入(盡管當你投射某些東西時它總是會相信你)。
通用的“display()”方法如下所示:
public static void main(String a[]) {
List<String> list = new ArrayList<String>();
list.add("Gunjan");
list.add("Shah");
new Sample_2().display(list);
}
public <T> void display(List<T> list) {
for (T t : list) {
System.out.println(t);
}
}
在泛型方法中使用泛型時,必須引用泛型值,就像它們是名為T
的對象類型一樣
我認為您將 String 對象放入 List 中,然后創建String 類型的List 。
public List<String> testReturn(){
List<String> list = new ArrayList<String>();
list.add("Gunjan");
list.add("Parth");
list.add("Devang");
return list;
}
泛型可以與類、方法、變量一起使用,但最重要的是使用它使集合更加類型安全
<T>
被稱為類型參數,如果在方法中使用 this,則表示這是方法中遇到type T
的參數時要使用的type T
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.