Java 具有仿制药的消费者
试图与消费者一起理解泛型Java 具有仿制药的消费者,java,generics,consumer,Java,Generics,Consumer,试图与消费者一起理解泛型 class Fruit{} class Apple extends Fruit{} class Orange extends Fruit{} class Util{ private Collection<Apple> appleList = new ArrayList<>(); public Util(){ acceptFruit(ap -> appleList.add(ap); } p
class Fruit{}
class Apple extends Fruit{}
class Orange extends Fruit{}
class Util{
private Collection<Apple> appleList = new ArrayList<>();
public Util(){
acceptFruit(ap -> appleList.add(ap);
}
public <T extends Fruit> void acceptFruit(Consumer<T> fruitConsumer){
//FruitService.getAllFruits();
//some validations and get fruit object
fruitConsumer.accept(fruit);
}
}
//Some other class calling Util.acceptFruit(orange -> oranges.add(orange);
及
fruit.accept(fruit);
accept (T) in Consumer cannot be applied to (Apple)
由于Apple
正在扩展Fruit
,我不明白为什么会出现这个错误?你知道我在泛型/消费者概念中遗漏了什么吗?你的acceptFruit()
很奇怪,因为它调用fruit.accept(fruit)
。这段代码将消费者本身作为参数调用,从而导致泛型中的所有混乱。您必须将apple实例传递给消费者,因此以下是您的代码,没有错误:
class Util {
private Collection<Apple> appleList = new ArrayList<>();
public Util(){
acceptFruit(ap -> appleList.add(ap), new Apple());
}
public <T extends Fruit> void acceptFruit(Consumer<T> fruitConsumer, T fruit){
//FruitService.getAllFruits();
//some validations and get fruit object
fruitConsumer.accept(fruit);
}
}
class-Util{
私有集合appleList=new ArrayList();
公共Util(){
acceptFruit(ap->appleList.add(ap),newapple());
}
公共水果(消费水果消费者,T水果){
//getAllFruits();
//一些验证和获取水果对象
水果消费者。接受(水果);
}
}
您的acceptFruit()
很奇怪,因为它调用了fruit.accept(fruit)
。这段代码将消费者本身作为参数调用,从而导致泛型中的所有混乱。您必须将apple实例传递给消费者,因此以下是您的代码,没有错误:
class Util {
private Collection<Apple> appleList = new ArrayList<>();
public Util(){
acceptFruit(ap -> appleList.add(ap), new Apple());
}
public <T extends Fruit> void acceptFruit(Consumer<T> fruitConsumer, T fruit){
//FruitService.getAllFruits();
//some validations and get fruit object
fruitConsumer.accept(fruit);
}
}
class-Util{
私有集合appleList=new ArrayList();
公共Util(){
acceptFruit(ap->appleList.add(ap),newapple());
}
公共水果(消费水果消费者,T水果){
//getAllFruits();
//一些验证和获取水果对象
水果消费者。接受(水果);
}
}
苹果
可能是水果
,但集合
不是集合
。这是由于泛型类型的不变性
忽略acceptFruit
内部的编译错误(我完全不清楚您首先要做什么),最好的方法是确保集合包含要与之接口的超类,而不是任何子类
private Collection<Fruit> fruitList = new ArrayList<>();
private Collection foultlist=new ArrayList();
这样,你可以在你的消费者身上食用任何你想要的水果
任何比这更高级的东西——也就是说,食用特定种类的水果——都比我们这里的基本仿制药更高级,最好留给读者作为练习。Apple
可能是水果
,但Collection
是而不是Collection
。这是由于泛型类型的不变性
忽略acceptFruit
内部的编译错误(我完全不清楚您首先要做什么),最好的方法是确保集合包含要与之接口的超类,而不是任何子类
private Collection<Fruit> fruitList = new ArrayList<>();
private Collection foultlist=new ArrayList();
这样,你可以在你的消费者身上食用任何你想要的水果
任何比这更高级的东西——也就是食用特定种类的水果——都比我们这里的基本泛型更高级,最好留给读者作为练习。Apple
是水果的子类型,但是Apple
不知道是T
的子类型,这是一种未知类型T
可以是水果
,或橙色
,或香蕉
,通常苹果
不能是所有这些的子类型
声明acceptFruit
方法的方式没有真正意义,因为作为一个通用方法,这意味着无论t
是什么,它都必须工作。acceptFruit
的调用者可以使用调用者想要的T
来调用它,并且acceptFruit
必须在不知道T
是什么的情况下正常工作。因此,acceptFruit
接受一个参数,Consumer
,但是acceptFruit
在运行时不知道Consumer
想要什么类型——它可能是Consumer
一个调用,而消费者
下一个调用--但是acceptFruit
无法推断特定调用中需要什么类型,因为它没有任何其他参数来告诉它它是什么。为了调用fruitConsumer
,它需要传入一个未知类型的实例。因此,acceptFruit
可以安全编写的唯一方法是:1)它根本不调用fruitConsumer
;或者2)它总是将null
传递到fruitConsumerApple
是Fruit
的子类型,但是Apple
不知道是T
的子类型,这是一个未知类型T
可以是水果
,或橙色
,或香蕉
,通常苹果
不能是所有这些的子类型
声明acceptFruit
方法的方式没有真正意义,因为作为一个通用方法,这意味着无论t
是什么,它都必须工作。acceptFruit
的调用者可以使用调用者想要的T
来调用它,并且acceptFruit
必须在不知道T
是什么的情况下正常工作。因此,acceptFruit
接受一个参数,Consumer
,但是acceptFruit
在运行时不知道Consumer
想要什么类型——它可能是Consumer
一个调用,而消费者
下一个调用--但是acceptFruit
无法推断特定调用中需要什么类型,因为它没有任何其他参数来告诉它它是什么。为了调用fruitConsumer
,它需要传入一个未知类型的实例。因此,acceptFruit
可以安全编写的唯一方法是:1)它根本不调用fruitConsumer
;或者2)它总是将null
传递到fruitConsumer
阅读(或者)。