为什么不能将B的超类对象放入Container <?超级B>?

问题描述

我有下面的代码。看来我无法将\w类的超类的Nonlife类的对象放到Vehicle类型的容器中。 ALTHOUGH 通配符类型中的“ super”,只有类Collection<? super Vehicle>的子类VehicleSUV的对象才可行。有人可以给我一些建议吗?

Vehicle

解决方法

对于public void insertImage(View view) { Intent chooseFile; Intent intent; chooseFile = new Intent(Intent.ACTION_GET_CONTENT); chooseFile.setType("*/*"); chooseFile.addCategory(Intent.CATEGORY_OPENABLE); intent = Intent.createChooser(chooseFile,"Choose a file"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivityForResult(intent,PICKFILE_RESULT_CODE); } @Override protected void onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode,resultCode,data); switch (requestCode) { case PICKFILE_RESULT_CODE: if (resultCode == RESULT_OK) { Uri uri = data.getData(); String str = data.getData().toString(); String mimeType = getContentResolver().getType(uri); try { // User content resolver to get uri input stream. InputStream inputStream = getContentResolver().openInputStream(uri); // Get the bitmap. Bitmap imgBitmap = BitmapFactory.decodeStream(inputStream); // Show image bitmap in imageview object. imageView.setImageBitmap(imgBitmap); }catch(FileNotFoundException ex) { Log.e(TAG,ex.getMessage(),ex); } } break; } } 唯一可以肯定的是它是Vehicle的集合,或者是Vehicle的超类型的集合。因此,您唯一可以确定可以放入此集合的东西是Vehicles。因此,您可以将NonLifes的Collection传递给该方法,但仍可以只将Vehicles或子类型放入该方法中的Collection。

通常:使用super时,您可以将提到的类型或子类型的值放入其中。使用扩展,您可以从集合中检索提到的类型,也可以将它们作为超类型检索。

,

这是一个Wildcard Capture问题。

TL; DR-在通用集合类型定义中使用通配符(与superextends一起使用时,可以认为从该集合中获取元素并将其正确转换为安全,而没有向集合中添加元素,则出于安全目的实施此机制。

让我们研究一下Oracle文档中给出的example,它说明了为什么需要这种安全性的原因(此示例使用extends,但是相同的原理也适用于super ):

代码:

import java.util.List;

public class WildcardErrorBad {

    void swapFirst(List<? extends Number> l1,List<? extends Number> l2) {
        Number temp = l1.get(0);
        l1.set(0,l2.get(0)); // expected a CAP#1 extends Number,got a CAP#2 extends Number;
        l2.set(0,temp); // expected a CAP#1 extends Number,got a Number
    }
}

尝试进行不安全操作时不会编译,因为,如果要按以下方式调用此方法:

List<Integer> li = Arrays.asList(1,2,3);
List<Double>  ld = Arrays.asList(10.10,20.20,30.30);
swapFirst(li,ld);

虽然List<Integer>List<Double>都符合List<? extends Number>的条件,但从整数值列表中取出一项并将其放入Double列表中显然是不正确的值。

Jon Skeet给出了我喜欢的另一个示例,它看起来像this

您可能还想阅读this