Java基础笔记之泛型

泛型

泛型是JDK1.5之后出现的新特性,泛指某一种数据类型,当使用一个类、方法、接口不确定要使用什么数据类型的时候,或者说不确定要用来处理哪种数据类型的时候可以定义为泛型。

使用泛型的好处

1.在谈使用泛型的好处之前,先说一下不使用泛型的情况。
例如,在集合创建时,不使用泛型,那么会默认为Object类型,可以储存任意数据类型

public class Demo08Generic {
    public static void main(String[] args) {
        //不使用泛型
        Collection list = new ArrayList();
        list.add("abc");
        list.add(12345);
        Iterator it = list.iterator();
        //可以使用迭代器把不同的数据类型同时打印
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

在集合中放入不同的数据类型,程序不会报错,下面是输出结果:

abc
12345

但是不使用反映,弊端也是很明显的,而且编译的时候不会报错,运行的时候才会报错
比如上面的程序中,如果想使用字符串的API接口方法length( )获取字符串的长度时

public class Demo08Generic {
    public static void main(String[] args) {
        //不使用泛型
        Collection list = new ArrayList();
        list.add("abc");
        list.add(12345);
        Iterator it = list.iterator();
        //可以使用迭代器把不同的数据类型同时打印
        while(it.hasNext()){
            System.out.println(it.next());
            String str = (String)it.next();
            System.out.println(str);
        }
        
    }
}

上面的程序在编译时不会报错,但是运行会报错:ClassCastException(类转换异常)

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
	at com.itheima.demo03.Generic.Demo08Generic.main(Demo08Generic.java:21)

2.如果使用泛型,可以避免程序在运行时报错,因为它会把这类错误提前到程序编译时抛出异常,可以提前发现。
当确实集合的类型为String类型时,如果加入整形的数据类型,编译会直接报错。

public class Demo08Generic {
    public static void main(String[] args) {
        //使用泛型
        Collection<String> list = new ArrayList<>();
        list.add("abc");
        list.add(12345);//编译抛出异常 add(java.lang.String) in Colletion cannot be applied to (int)
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

    }
}

定义含有泛型的类、方法、接口

1、定义泛型的类

定义一个泛型类,可以把类中的成员变量和成员方法都定义为泛型(成员变量和成员方法也可以定义为具体的数据类型,不过这样就失去了定义为泛型类的意义了)。
格式:

public class GenericClass<E> {
    public E name;
    
    public <E> void method(E e){
        //方法体
    }
}

泛型类在创建对象时,确认泛型的类型

public class Demo01GenericClass {
    public static void main(String[] args) {
        GenericClass<String> gc = new GenericClass<>();
        gc.name="夸父";
        System.out.println(gc.name);
    }
}

2、定义含有泛型的方法

格式与上面的泛型类中定义的泛型方法一致;

public class GenericClass<E> {
    //可以修改为把泛型当做返回值,穿进来什么数据类型,返回的就是什么数据类型
    public <E> E method(E e){
        return e;
    }
}

使用:在调用方法的时候确定泛型的数据类型,传递什么数据类型的参数,泛型就是什么类型

public class Demo01GenericClass {
    public static void main(String[] args) {
        GenericClass<String> gc = new GenericClass<>();
        //传入的是double类型,返回的就是double类型
        Double method1 = gc.method(34567.12);
    }
}

还可以定义含有泛型的静态方法,格式:

public static <S> void MethodStatic(S s){
        System.out.println(s);
    }

静态方法用类名直接调用(类名.静态方法名)

public class Demo01GenericClass {
    public static void main(String[] args) {
        GenericClass.MethodStatic("女娲");
    }
}

3、定义含有泛型的接口

格式:

public interface GenericInterface<I> {
    public abstract void methodInterface(I i);
}

泛型接口的使用方式有两种,一种是:定义接口的实现类,指定接口的泛型

public class GenericInterfaceImpl implements GenericInterface<String> {
    //重写接口的方法也跟着确定了类型
    @Override
    public void methodInterface(String s){
        System.out.println(s);
    }
}

第二种使用方式:把接口的实现类也写成含有泛型的格式,创建对象时再确定泛型的类型

public class GenericInterfaceImpl1<E> implements GenericInterface<E> {
    @Override
    public void methodInterface(E e){
        System.out.println(e);
    }
}

创建对象,并确定泛型的数据类型

public class Demo01GenericClass {
    public static void main(String[] args) {
        GenericInterfaceImpl1<String> gc1 = new GenericInterfaceImpl1();
        gc1.methodInterface("天天向上");

    }
}

泛型的通配符

泛型的通配符:?
表示任意的数据类型
泛型通配符的高级用法:
1、<? extends E>:代表使用的泛型只能是E类型的子类或者本身
2、<? super E> :代表使用的泛型只能是E类型本身或者父类
例如

    public static void getElement(Collection<? extends Number> coll){
        //此时的泛型?,必须是Number类型或者是Number类型的子类
    }
    public static void getElement1(Collection<? super Number> coll){
        //此时的泛型?,必须是Number类型或者是Number类型的父类
    }

注意事项:泛型的通配符不能在创建对象的时候使用,可以作为方法的参数使用

总结

实际开发中,泛型很常见,框架中也很多地方使用,系统的把泛型过一遍,这样在读代码的时候,遇到使用泛型的地方,不会不理解了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值