泛型

 

 

泛型<E>

 1.使用泛型的好处

  1.可以统一数据类型,便于操作。
  2.将运行时的异常提前到了编译时,提高了效率。
  3.避免了强制类型转换
  4.实现代码的模板化,把数据类型当作参数传递,提高了可重用性。

 2.泛型的定义

  1.定义在类上

public class MyClass1<E> {
    /*
    * 定义具有泛型的类
    * 修饰符 class 类名 <范型变量>{
    * 范型变量一般用E,K,V,T;
    * }
    * */
    private E e;

    public MyClass1() {
    }

    public MyClass1(E e) {
        this.e = e;
    }

    public E getE() {
        return e;
    }

    public void setE(E e) {
        this.e = e;
    }

    @Override
    public String toString() {
        return "MyClass1{" +
                "e=" + e +
                '}';
    }

    public void print(){
        System.out.println(e);
    }
}

定义在类上的泛型是在创建对象时确定的。
  2.定义在方法上

/*
    泛型方法(方法上含有泛型)
    格式:
        修饰符 <泛型变量> 返回值类型 方法名称(参数列表...) {
            //...
        }
 */
public class MyClass02<T> {
    //此方法上的泛型不是自己定义的,而是使用的类上的泛型
    public void print(T t) {
        System.out.println(t);
    }
    //泛型方法: 泛型E是在方法上自己定义的
    public <E> void show(E e) {
        System.out.println(e);
    }
}

创建在放方法上的泛型是在真正调用方法时确定,一般都由传入的参数确定,包含这个方法的类创建对象时,并不会确定方法上的类型,一定在调用方法时确定。
  3.定义在接口上

/*
    泛型接口(接口上含有泛型)
    格式:
        public abstract interface 接口名<泛型变量> {
            //抽象方法
        }
 */
public interface MyInter<T> {
    //抽象方法
    public abstract void print(T t);
}

由实现类对象确定。

 3.使用泛型注意

  1.泛型在使用时确定,但如果提前知道泛型类型也可以在定义时确定泛型类型,但这样做体现不了泛型的优势与强大。
  2.泛型不存在继承,即在确定了泛型时,其操作中相对应的泛型必须一致。不能存在继承或者多态的关系,即<>内的类型必须一致,不能不同。但使用泛型的对象依然是可以存在继承或者多态的关系,即<>外的东西存在继承或者多态。
  3.泛型只能是引用类型,不能是基本类型。

 4.泛型的上限和下限以及通配符。

  1.当使用泛型类或者接口时,(注意是使用泛型,不是定义泛型,两者之间存在很大差异)传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配 符后,里面的只能使用Object类中的共性方法,集合中元素自身方法无法使用。 具体如下所示

import java.util.ArrayList;

public class Demo02TongPeiFu {
    /*
    * 泛型在使用时必须左右一致,不存在继承;
    * */
    public static void main(String[] args) {
        ArrayList<?> list1 ;
        ArrayList<String> list2 = new ArrayList<String>();
        ArrayList<Integer> list3 = new ArrayList<Integer>();
        ArrayList<Object> list4 = new ArrayList<String>();//泛型在使用时必须左右一致,不存在继承;
        list1 = list2;
        list1 = list3;//不会报错,使用了通配符,通配符表示任意类型,这是在使用,把?当成任何一种类型,
                      //?就是任何类型。
        list2 = list3; //会报错  因为两者在定义时使用泛型,一旦确定了类型就不能够改变类型,
                      //只能是给定的一种泛型类型。
    }
    public static void print1(ArrayList<?> list) {
        //使用了通配符里面的元素被限定了只能使用Object的方法,
        //底层使用的是Object所以不能添加元素,因为不知道里面到底是什么类型的元素
        list.add(new Object());
        list.get(0);
        list.remove(0);
        list.set(0,new Object());
        for(Object obj : list) {
            System.out.println(obj);
        }
    }
    public static<E> void print2(E e,ArrayList<E> list) {//这是在定义
        //可以使用任何方法只要属于该类
        list.add(e);
        System.out.println(list);
    }
}

通配符

 5.泛型上限和下限

  当使用通配符时,你不想?代表所有类型,那样很没有意义,你想对类型有一定限定,这时就要使用到上限和下限了。<? extends 类名>意思是说,?能代表的类型只能是指定类的子类,所以叫泛型上限。<?super 类名>意思是说,?能代表的类型只能是指定类的父类,所以叫泛型下限。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值