JAVA:如何在泛型函数中返回值
我正在用JAVA泛型概念测试一些小的实践 我试图从一个泛型函数返回一个列表,但compile不允许我这样做 检查以下代码:JAVA:如何在泛型函数中返回值,java,generics,Java,Generics,我正在用JAVA泛型概念测试一些小的实践 我试图从一个泛型函数返回一个列表,但compile不允许我这样做 检查以下代码: package com.test.generic.method; 导入java.util.ArrayList; 导入java.util.List; 公共类样本3{ 公共列表测试返回(T){ List=newarraylist(); 列表。添加(t); 退货清单; } 公共静态void main(字符串a[]{ 字符串s=“Gunjan”; 样本_3样本=新样本_3(); L
package com.test.generic.method;
导入java.util.ArrayList;
导入java.util.List;
公共类样本3{
公共列表测试返回(T){
List=newarraylist();
列表。添加(t);
退货清单;
}
公共静态void main(字符串a[]{
字符串s=“Gunjan”;
样本_3样本=新样本_3();
List=(List)sample.testReturn(sample);
for(字符串ab:列表){
系统输出打印LN(ab);
}
}
}
它给出了ClassCastException
如何从泛型函数返回列表?
为什么JAVA添加了这样的编译时特性
谢谢,
Gunjan.您需要签名:
public List<String> testReturn()
公共列表testReturn()
当您在方法声明中使用
时,它会告诉编译器您希望基于传入的一个参数在方法中使用泛型类型。因为您没有传递任何类型为T
的参数,编译器无法将T
解析为类型。我认为您正在将字符串对象放入列表中,然后创建类型字符串的列表
public List<String> testReturn(){
List<String> list = new ArrayList<String>();
list.add("Gunjan");
list.add("Parth");
list.add("Devang");
return list;
}
公共列表testReturn(){
列表=新的ArrayList();
列表。添加(“Gunjan”);
列表。添加(“第方”);
列表。添加(“德旺”);
退货清单;
}
泛型可以与类、方法、变量一起使用,但它的最重要的用途是使集合更加类型安全
称为类型参数,如果在方法中使用该参数,则意味着,当遇到类型为T的参数时,该类型将在方法中使用。因此,您可以执行以下操作:
public List<T> testReturn(T t){
List<T> list = new ArrayList<T>();
list.add(t);
return list;
}
公共列表testReturn(T){
列表=新的ArrayList();
列表。添加(t);
退货清单;
}
这将允许您执行以下操作:
List<String> a = testReturn("A");
List<Integer> b = testReturn(1);
List a=testReturn(“a”);
列表b=测试返回(1);
代码的问题在于,方法的意图并不是真正的泛型——编写该方法是为了返回一个列表。代码中的
实际上不会影响任何东西
回应你的进一步质询—
您已经编写了以下内容:
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);
}
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);
}
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);
}
}
公共类示例\u 3{
公共列表测试返回(T){
List=newarraylist();
列表。添加(t);
退货清单;
}
公共静态void main(字符串a[]{
字符串s=“Gunjan”;
//这是错误的-示例_3类不是泛型的。它没有获取泛型类型参数。
样本_3样本=新样本_3();
//这也是错误的,因为方法是泛型的,所以得到的“T”与得到的“T”相同
//进入方法。此处字符串输出类型与方法的输入类型不匹配,
//您在这里将其设置为示例_3对象
List=(List)sample.testReturn(sample);
}
您的泛型参数T设置可以变化的类型。您可以在方法级别(如上所述)或类级别执行此操作:
public class Sample_3<T> {
public List<T> getList(){ ... }
}
公共类示例\u 3{
公共列表getList(){…}
}
e、 g
List l=新样本_3().getList();
列表s=新样本_3().getList();
列表c=新样本_3().getList();
您正在指定T列表的返回类型,但返回字符串列表。快速修复方法是:
public List<String> testReturn(){
List<String> list = new ArrayList<String>();
// add stuff to list;
return list;
}
公共列表testReturn(){
列表=新的ArrayList();
//在列表中添加内容;
退货清单;
}
实际上,泛型的目的是允许您泛化类(即示例)因此,您可以创建它的新实例,但指定它为每个实例处理什么类型的对象。Java在编译时检查这些泛型。以列表为例—没有泛型,它不关心我将哪些对象放入列表—这意味着我可能会在没有得到警告的情况下放入一个Double,并且我不知道是什么类型的O调用get()时包含的对象。我们可以编写新的类或列表实现,这些类或实现仅限于特定对象(例如,StringList只能接受字符串),但这将非常耗时,并且可能很难维护。相反,Java泛型允许我们将特定列表的输入/输出限制为特定类(以及该类的任何实现)-例如,List只接受和返回字符串
e、 g.要使样本通用化:
public class Sample<T> {
public List<T> makeEmptyList(){
return new ArrayList<T>();
}
}
公共类示例{
公共列表makeEmptyList(){
返回新的ArrayList();
}
}
也可以在静态方法中指定泛型,但必须将泛型类型作为对象或类引用传入:
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>();
}
publicstaticlist-makeAndAddToList(T){
列表=新的ArrayList();
列表。添加(t);
退货清单;
}
公共静态列表makeEmptyList(类clazz){
返回新的ArrayList();
}
在您的例子中,不清楚您的示例类是否应该限制为处理字符串和列表,或者是否应该将其设置为泛型
要了解更多信息,请查看。我认为要问的第一个问题是,当您在方法中显式创建列表时,为什么要声明返回列表的方法?该示例不会通过使用泛型为您带来任何好处。您是否正在尝试解决其他情况
为了给您上一课,当Java编译类时,会从字节码中删除泛型。因此,在编辑器中最初可能是这样的:
public <T> List<T> testReturn(){
}
public List<String> 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);
}
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);
}
}