Java开发——24.泛型

泛型:

我们查看API帮助文档可知,Collection接口的定义格式为Interface Collection,那么代表什么呢?E - 此集合中元素的类型 !为什么要用<>括起来呢?就是我们将要学习到的泛型。

学习思路:

在这里插入图片描述

泛型的通配符:

泛型中的通配符有四种:T、E、K V、?

泛型有以上四种定义格式;

T Java的类型的是一个形参!在方法声明的时候使用。一般指代泛型类。

E 通常用于规定集合中的元素类型。

K V 一般表示Java中Map集合的键值对。

==?==一般表示不确定的Java类型,这是一种无限的符号,代表任何类型都可以。是一个实参!在方法使用的时候直接调用,但是 ?不能作为元素类型添加值,也就是 ?只能在没有定义元素类型的时候接收不同类型的元素。

?一般只是接收某种数据类型,并不能作为返回值;

?extends XX:向下限定,E及其子类;

? super XX:向上限定,E极其父类。

(在后面详细讲解 ?请继续学习。)

在学习Collection集合的时候,我们了解到,集合可以存储任意类型的元素,那么我们如果在使用增强for循环遍历集合的过程中,不使用Object接收对象,而使用特定的元素类型,就会爆出ClassCastException异常,表示类型转换异常,类型不兼容;

public static void main(String[] args) {//此处指定了Collection集合的类型为Integer,所以不能添加别的元素类型
        Collection<Integer> num = new ArrayList();
        num.add(123);
        num.add(456);
        num.add(789);
       // num.add("123");在编译的时候都会报错//我们定义了一个没有指定类型的Collection集合
        Collection str = new ArrayList();
        str.add("123");
        str.add("456");
        str.add("789");//因为指定集合的元素类型<E>,只会在编译的时期判断,存入的内容类型
//在运行时会把元素类型都默认为Object类型,这就叫做“泛型的擦除”
        num.addAll(str);//在增强for循环的时候我们使用了Integer作为元素输出类型
//但是num集合中是存在String类型的元素的,所以会存在类型不兼容无法完成遍历
        for (Integer in : num){
            System.out.println(in);
        }
}

在这里插入图片描述

泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。

泛型类:

<数据类型> 此处的数据类型只能是引用类型。

好处:

A:把运行时期的问题提前到了编译期间 ;

B:避免了强制类型转换。

/*
 * 泛型类:把泛型定义在类上
 */
public class ObjectTool<T> {private T obj;public T getObj() {
        return obj;
    }public void setObj(T obj) {
        this.obj = obj;
    }}
/*
 * 泛型类的测试
 */public class ObjectToolDemo {
    public static void main(String[] args) {ObjectTool<String> ot = new ObjectTool<String>();//规范了数据的存储
​
        ot.setObj(new String("江一燕"));
        String s = ot.getObj();
        System.out.println("姓名是:" + s);ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
        ot2.setObj(27);
        Integer i = ot2.getObj();
        System.out.println("年龄是:" + i);
    }
}

泛型方法:

修饰符 <代表泛型的变量> 返回值类型 方法名 (参数){ }

//普通方法
//修饰符 返回值类型 方法名(参数){}
public int show(int i){
        return i;
    }/*
 * 泛型方法:把泛型定义在方法上
 */
    public <T> Object show(T t) {
        return t;
    }
    
     //定义一个泛型方法
    //返回类型不应该明确,因为泛型方法的类型都不明确
    //建议:Object 或者  T(泛型)
    public <T> T show(T t){
        return  t;
    }
//实现类
public class TestCollection {public <T> Object show(T t){
        return t;
    }public <T> T show2(T t){
        return t;
    }public int show(int i){
        return i;
    }public static void main(String[] args) {
        System.out.println(new TestCollection().show(1111111111));
        System.out.println(new TestCollection().show("2222222222"));
        System.out.println(new TestCollection().show2(new Date()));
    }
}
/*
1111111111
2222222222
Tue May 03 16:03:35 CST 2022
*/

泛型接口:

修饰符 interface 接口名<代表泛型的变量> { }

/*
 * 泛型接口:把泛型定义在接口上
 */
public interface Inter<T> {
  public abstract void show(T t);
}
//实现类在实现接口的时候//第一种情况:已经知道该是什么类型的了
public class InterImpl implements Inter<String> {@Override
  public void show(String t) {
    System.out.println(t);
  }
}//第二种情况:还不知道是什么类型的
public class InterImpl<T> implements Inter<T> {@Override
  public void show(T t) {
    System.out.println(t);
  }
}
//测试类
public static void main(String[] args) {
        //第一种情况:实现类已经明确类型,实例化对象时必须与实现类中的类型一致
        InterDemo<String> i = new InteImpl();//我在实现的时候,已经明确类型--String
        i.show("aaa");
        i.show("bbb");
      
        //第二种情况:实现类也没有明确类型
        InterDemo<Integer> ii = new InteImpl2<>();//我在实现的时间也没有给出明确
        ii.show(11);
        ii.show(22);InterDemo<String> ii2 = new InteImpl2<>();//我在实现的时间也没有给出明确
        ii2.show("11");
        ii2.show("22");
    }
}

当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。

关于 ?通配符:

泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知通配符。此时只能接受数据,不能往该集合中存储数据。

/*
 * 泛型高级(通配符)
 * ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
 * ? extends E:向下限定,E及其子类
 * ? super E:向上限定,E极其父类
 */
public class Animal {
}public class Dog extends Animal {
}public class Cat extends Animal {
}
​
​
public class GenericDemo {
  public static void main(String[] args) {
    // 泛型如果明确的写的时候,前后必须一致
    Collection<Object> c1 = new ArrayList<Object>();
    //错误写法:
    // Collection<Object> c2 = new ArrayList<Animal>();
    // Collection<Object> c3 = new ArrayList<Dog>();
    // Collection<Object> c4 = new ArrayList<Cat>();// ?表示任意的类型都是可以的
    Collection<?> c5 = new ArrayList<Object>();
    Collection<?> c6 = new ArrayList<Animal>();
    Collection<?> c7 = new ArrayList<Dog>();
    Collection<?> c8 = new ArrayList<Cat>();// ? extends E:向下限定,E及其子类,表示包括E在内的任何子类;
    // Collection<? extends Animal> c9 = new ArrayList<Object>();
    Collection<? extends Animal> c10 = new ArrayList<Animal>();
    Collection<? extends Animal> c11 = new ArrayList<Dog>();
    Collection<? extends Animal> c12 = new ArrayList<Cat>();// ? super E:向上限定,E极其父类,表示包括E在内的任何父类;
    Collection<? super Animal> c13 = new ArrayList<Object>();
    Collection<? super Animal> c14 = new ArrayList<Animal>();
    // Collection<? super Animal> c15 = new ArrayList<Dog>();
    // Collection<? super Animal> c16 = new ArrayList<Cat>();
  }
}

欢迎关注微信公众号:小红的成长日记,一起学Java!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值