Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-使用泛型返回多个类型_Java_Generics_Methods_Return - Fatal编程技术网

Java-使用泛型返回多个类型

Java-使用泛型返回多个类型,java,generics,methods,return,Java,Generics,Methods,Return,我有一个这样的方法- public List<Apples> returnFruits(String arg1){ List<Apples> fruits = new ArrayList<Apples>(); Apple a = new Apple(); fruits.add(a); return fruits; } 传递的结果不在相同的类层次结构中,并且是不同的类型 谢谢。Java通过擦除实现泛型,所以在运行时不知道传入了哪种泛型类型。也不可能new创建

我有一个这样的方法-

public List<Apples> returnFruits(String arg1){
List<Apples> fruits = new ArrayList<Apples>();
Apple a = new Apple();
fruits.add(a);

return fruits;
}
传递的结果不在相同的类层次结构中,并且是不同的类型


谢谢。

Java通过擦除实现泛型,所以在运行时不知道传入了哪种泛型类型。也不可能
new
创建泛型类型,因为您不能保证传入的类型将具有无参数构造函数

可以将类本身作为实参数传入:

public <T> List<T> returnFruits(String arg1, Class<T> clazz){
公共列表(字符串arg1,类clazz){

…但是,您需要使用反射来实例化该类的新版本,并祈祷用户不要提供没有默认构造函数的类。

如果您确定将使用无参数构造函数,则可以使用以下语法:

public <T> List<T> returnFruits(Class<T> clazz){
    List<T> fruits = new ArrayList<T>();
    T t = clazz.newInstance();
    fruits.add(t);

    return fruits;
}
公共列表(类clazz){
列表结果=新的ArrayList();
T=clazz.newInstance();
添加(t);
还果;
}
用法:

List<MyClass> m = returnFruits(MyClass.class, "plop");
List<MyClass> m = returnFruits(MyClass.class, "plop");
List m=returnFruits(MyClass.class,“plop”);
如果您知道有一个带字符串参数的构造函数:

public <T> List<T> returnFruits(Class<T> clazz, String arg1){
    List<T> fruits = new ArrayList<T>();
    Constructor<T> constructor = clazz.getConstructor(String.class);
    T t = constructor.newInstance(arg1);
    fruits.add(t);

    return fruits;
}
公共列表(类clazz,字符串arg1){
列表结果=新的ArrayList();
Constructor=clazz.getConstructor(String.class);
T=constructor.newInstance(arg1);
添加(t);
还果;
}
用法:

List<MyClass> m = returnFruits(MyClass.class, "plop");
List<MyClass> m = returnFruits(MyClass.class, "plop");
List m=returnFruits(MyClass.class,“plop”);
等等{ 苹果a=新苹果(); 列表=新的ArrayList; 列表.添加(a); 退货清单; } 应该可以。基本上,在方法之前声明您想要类型“T”的列表。然后您可以返回任何类型“T”的列表。基本上,您不能执行“new T()”,因为它没有任何类型信息。它必须是一个concreate类


如果需要,您甚至可以将该类类型作为参数传入。

您可以采取多种方法。一种是按照其他人的建议使用
class
。另一种方法是创建某种生产者界面,并传入:

public interface FruitProducer<T> {
    T createFruit(String arg);
}

public <T> List<T> returnFruits(String arg, FruitProducer<? extends T> producer) {
    List<T> list = new ArrayList<T>();
    T fruit = producer.createFruit(arg);
    list.add(fruit);
    return list;
}
现在您有了不同的列表器:
AppleLister实现了水果列表器
,等等。每个列表器都知道如何实例化它需要在列表中返回的特定类:

public class AppleLister implements FruitLister<Apple> {
    @Override
    public List<Apple> returnFruits(String arg) {
            List<Apple> list = new ArrayList<Apple>();
            Apple apple = new Apple(arg);
            list.add(apple);
            return list;
    }
}
公共类AppleLister实现了水果列表器{
@凌驾
公共列表(字符串参数){
列表=新的ArrayList();
苹果=新苹果(arg);
添加(苹果);
退货清单;
}
}

+1;我同意你的看法。不过,
clazz
有没有默认值(零参数)的风险构造函数。它会导致
newInstance
失败。我同意。看看这里的yshavit解决方案,提出一个带有接口生成器的伟大解决方案。;)谢谢你的解决方案。你知道我如何使用你的解决方案在对象类型上执行方法吗。所以,如果苹果有一个方法集颜色,我想我不能说没有。setColor();有方法调用该函数吗?谢谢。@Maryam听起来该方法确实需要了解苹果的情况——不仅是它的构造函数,现在还需要了解它的方法。你可以使用
instanceof
,但我认为多态方法会更好地为你服务。我格式化了你的代码,开始时只需使用4个空格,因此会将这一行识别为代码。这样,您就不必对HTML/XML实体进行编码。太好了!谢谢您的提示。可以了。:)
public abstract class FruitLister<T> {
    public abstract List<T> returnFruits(String arg);
}
public class AppleLister implements FruitLister<Apple> {
    @Override
    public List<Apple> returnFruits(String arg) {
            List<Apple> list = new ArrayList<Apple>();
            Apple apple = new Apple(arg);
            list.add(apple);
            return list;
    }
}