Java 逆变与协变的名词说明(2)

String[] s=new String[]{"hello"}; int[] i=new int[]{1,2,3}; //Array的具体实现是在虚拟机层面,嵌地非常深,也查不到源码 //只能用javap反编译看看具体初始化数组的字节码

下面是具体的反编译的字节码: 看注释说明,创建int数组和String数组的指令都不一样,换句话说,数组是Java中的特例,它嵌在虚拟机层面,从底层就决定了不支持泛型

Code:
     
0: iconst_1
     
1: anewarray    #2                  // class java/lang/String
      4: dup
     
5: iconst_0
     
6: ldc          #3                  // String hello
      8: aastore
     
9: astore_1
     
10: iconst_3
     
11: newarray      int
      13: dup
     
14: iconst_0
     
15: iconst_1
      ... ...

4:泛型中的协变(带通配符的泛型)

   看来协变的概念就应该很清楚的知道,泛型是不支持协变的。List<integer> 并不是 List<Number>的儿子。编译期就会报错,如下截图

Java 逆变与协变的名词说明

 

  于是,java设计者引入了通配符的概念,用于在泛型中提供协变这一功能。比如 我们希望有一个方法,它即可以接受宠物狗列表,也可以接受田园犬(是宠物狗的子类)列表,

于是我们引入协变。

package com.generic;

import java.util.ArrayList;
import java.util.List;

public class PetShow {
   
   
public void run(List<? extends ChongWuGou> dogs){
        System.out.println(
"running");
    }
   
public static void main(String [] args){
        List
<ChongWuGou> cDogs = new ArrayList<ChongWuGou>();
        List
<TianYuanQuan> tDogs = new ArrayList<TianYuanQuan>();
       
new PetShow().run(tDogs);//该方法可以正确运行
    }
}
//宠物狗
class ChongWuGou{
   
}
class TianYuanQuan extends ChongWuGou{
   
}

二:逆变

   在Java中不允许将父类变量赋值给子类变量。泛型自然也不支持逆变。但是在泛型中可以通过通配符进行模拟

public class Test
{
   
public static void main(String[] args)
    {
        List
<? super Integer> list = new ArrayList<Number>();
    }
}

  ? super Integer的含义是:支持Integer的父类,也包括Integer类,作为泛型的参数。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/3967ac9cac97c29b886645d60d9a77b1.html