泛型 --------类型参数化

1.泛型参数 T 

     表示一种数据类型,相当于形参,在使用时指定(只能传引用数据类型),默认值:Object

public class Point<T>{                 //      <T,R>    type    return

        T  x;                                     //         T x;

        T  y;                                     //        R y;

}

 使用:

Point<Integer>    p1 = new Point<Integer>();   //可以只有一对<>,后面的实参<> 可以省略

p1.x=1;     p1.y=2;

  

Point<String>    p2 = new Point<String>();

p2.x="1";     p2.y="2";

Point    p3 = new Point();

p3.x= new Object();     p3.y = new Object() ;

2.集合的泛型

(1)在编译时解决类型不一致问题(只在运行时出现)

集合中如果存储的数据类型不一致,就会在强制转换的时候出现类型转换异常

public int sum(List list){          //public int sum(List<Integer> list){
   int sum=0;
    for (Object o : list) {
         Integer i=(Integer)o;       //for (Integer i : list) {
         sum+=i;
    }
    return sum;
    }//在传入list几何1中存在Integer以外的类型的数据时,ClassEastException
List<Integer> list =new ArrayList<Integer>();

(2)如果在使用Collection接口的时候,给泛型参数指定了具体类型,那么就会防止出现类型转换异常的情 况,因为这时候集合中添加的数据已经有了一个规定的类型,其他类型是添加不进来的。

Map<String,Integer> map = new HashMap<>(); 

map.put("张三",20)

Collection<String> c = new ArrayList<String>(); 

3.泛型的种类:泛型类、 泛型接口、 泛型方法

public class Point<T>{

  }

Point<String> point = new Point<String>();

interface Animal<T,R>{

    R show(T t);

}

class AnimalImpl  implements Animal<String,Integer>{ //这块写T、R 会出错

//如果到这一步还是不能确定T、R,可以将类定义为泛型类

class AnimalImpl<T,R>  implements Animal<T,R>{

}                      //在实际类中尽量将泛型类型确定

public <T>  R show( T   t ){    //<T>在所有修饰符之后

        return t;

}

public void show1(){

        this.show("hello");

        this.show(10);}

4.泛型的类型

Object o = new Integer(1);       //编译通过

Object[]  arr = new Integer[1];   //Object[]类型兼容所有的【引用】类型数组

Object[] arr = new int[1];            //编译报错,类型不兼容

ArrayList<Object>    list = new ArrayList<Integer>();  //错误         

//在编译期间,ArrayList和ArrayList是俩个不同的类型,并且没有子父类型的关 系

//-----------俩个类型,如果是当做泛型的指定类型的时候,就没有多态的特点了,=号俩边的泛型类型必须一致

5.通配符

 public void test1(Collection<Integer> c){

}               //只能接收泛型是Integer类型的集合对象

public void test(Collection<?> c){

}         ///test方法可以接收 泛型是任意类型的 Collection集合对象

List<?> list = new ArrayList<String>();  //错误    泛型擦除,

 6.泛型边界

     在泛型中使用 extendssuper 关键字,就可以对泛型的类型进行限制。即:规定泛型的上限和 下限。

(1)上限:将来引用list就可以接收泛型是 Number 或者 Number 子类型的List集合对象

List<? extends Number> list;

//list可以指向泛型是Number或者Number【子】类型的集合对象

List<? extends Number>   list1 = new ArrayList<Double>();

List<? extends Number>   list1 = new ArrayList<Integer>();

List<? extends Number>   list1 = new ArrayList<Number>();

使用场景:

  • 在声明泛型类或者泛型接口的时候【可以】使用

public class Point<T extends Number>{

         private T x;

         private T y;

interface Action<T extends Person>{

        public void test(T t);

}

  •  在声明泛型方法的时候【可以】使用

1 public  <T extends Action>   void test(T t);

  •  在声明变量的时候【可以】使用

public class Test{

         public void test(List<? extends Number> list){

}

}

public static void main(String[] args) {

        List<? extends Number> list = new ArrayList<Long>();

        t.test(list);

}

(2)下限: 将来引用list就可以接收泛型是 Number 或者 Number 父类型的List集合对象

List<? super Number> list = new ArrayList<Number>();

List<? super Number> list = new ArrayList<Serializable>();

List<? super Number> list = new ArrayList<Object>();

  • 在声明泛型类或者泛型接口的时候【不能】使用

//编译报错

public class Point<T super Number>{

        private T x;

        private T y;

}

//编译报错

interface Action<T super Person>{

        public void test(T t);

}

  • 在声明泛型方法的时候【不能】使用

//编译报错

public <T super Action>  void test(T t);

  • 在声明变量的时候【可以】使用

public class Test{

         public void test(List<? super Number> list){

}

}

public static void main(String[] args) {

        List<? super Number> list;

        list = new ArrayList<Number>();

        list = new ArrayList<>Object();

    

    //假设Student 继承了 Person

        List<? super Student> list;

        list = new ArrayList<Student>();

        list = new ArrayList<Person>();

        list = new ArrayList<Object>();

}

7.类型擦除、泛型擦除

    泛型类型仅存在于编译期间,编译后的字节码和运行时不包含泛型信息,所有的泛型类型映射到同一份 字节码。

    Java让编译器擦除掉关于泛型类型的信息,这样使得Java 可以向后兼容之前没有使用泛型的类库和代码,因为在字节码(class)层面是没有泛型概念的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值