• Java学习笔记——泛型


    唧唧复唧唧

        ——木兰诗

    冗长的代码实在无趣,这就是为什么程序员会连自己写的代码都不愿意去看.看了就头痛,代码整洁才是关键.

    一、什么是泛型?为什么要使用泛型?

    且看代码:

     1 public class GenericsDemo {
     2 
     3     public static void main(String[] args) {
     4         List list = new ArrayList<>();
     5         list.add("1");
     6         list.add("2");
     7         list.add("3");
     8         list.add(5);//不小心把Integer丢进了集合中
     9         //编译不报错,运行时发生java.lang.ClassCastException异常
    10         list.forEach(str -> System.out.println((String)str));
    11     }
    12 }

    第8行代码不小心把Integer丢了进去,会引发ClassCastException

    使用了泛型后:

     1 public class GenericsDemo {
     2 
     3     public static void main(String[] args) {
     4         
     5         List<String> list = new ArrayList<>();
     6         list.add("1");
     7         list.add("2");
     8         list.add(3);//不小心把Integer丢进了集合中,编译报错
     9     }
    10 }

    第一段代码可能引发运行时异常ClassCastException的代码,在上面代码中直接编译报错了。

     1 public class GenericsDemo {
     2 
     3     public static void main(String[] args) {
     4         
     5         List<String> list = new ArrayList<>();
     6         list.add("1");
     7         list.add("2");
     8         list.add("3");
     9         list.add("4");
    10         list.forEach(str -> System.out.print(str));
    11     }
    12 }

    发现了么,第10行不用吧str强制转换为String类型了。

    1 public class GenericsDemo {
    2 
    3     public static void main(String[] args) {
    4         Object o = new Integer(10);
    5         Float f = (Float)o;
    6     }
    7 }

    程序在编译时并不知道你到底传了什么类型的变量。由于多态(想想猫和狗的例子),程序运行的的时候可能发生类型转换异常。

    为了避免ClassCastException运行时异常,Java引入泛型机制。

    使用泛型的好处:

    1、避免了ClassCastException

    2、免去了大量的强制转换

    二、定义泛型类和泛型接口

    上代码:

    使用泛型定义类(泛型定义接口的道理是一样的)

     1 public class Bag <T>{
     2 
     3     private T content;
     4 
     5     Bag(T content) {
     6         this.content = content;
     7     }
     8 
     9     T getContent() {
    10         return content;
    11     }
    12 
    13     void setContent(T content) {
    14         this.content = content;
    15     }
    16 }

    这里想下普通的定义方法,T是特定的类型(比如String)。这里的T可以是任意类型,类型范围很广。

    1 public class TestBag {
    2 
    3     public static void main(String[] args) {
    4         Bag<String> bag = new Bag<String>("book");
    5         Integer cintent = bag.getContent();//编译出错
    6         String content1 = bag.getContent();
    7     }
    8 }

    三、使用extends关键字限定类型参数

    上代码:

     1 public class LimitBag <T extends Number>{
     2 
     3     private T content;
     4 
     5     LimitBag(T content) {
     6         this.content = content;
     7     }
     8 
     9     T getContent() {
    10         return content;
    11     }
    12 
    13     void setContent(T content) {
    14         this.content = content;
    15     }
    16 }
    1 public class TestBag {
    2 
    3     public static void main(String[] args) {
    4     
    5         LimitBag<String> bag = new LimitBag<String>("book");//编译出错
    6         LimitBag<Integer> bag2 = new LimitBag<Integer>(1);//合法
    7     }
    8 }

    四、定义泛型数组

    上代码:

     1 public class GenericArray<T> {
     2 
     3     private T[] content;
     4 
     5     GenericArray(T[] content) {
     6         this.content = content;
     7     }
     8 
     9     T[] getContent() {
    10         return content;
    11     }
    12 
    13     void setContent(T[] content) {
    14         this.content = content;
    15     }
    16     
    17 }
     1 public class TestBag {
     2 
     3     public static void main(String[] args) {
     4                 
     5         String[] content = {"1","2","3"};
     6         GenericArray<String> ss= new GenericArray<>(content);
     7         for (String item : ss.getContent()) {
     8             System.out.println(item);
     9         }
    10     }
    11 }

    五、定义泛型方法

    上代码:

     1 public class MethodTest {
     2 
     3     public static <E> void printArray(E[] arr){
     4         for (E item : arr) {
     5             System.out.println(item);
     6         }
     7     }
     8     public static <T extends Comparable<T>> T max(T x,T y){
     9         return x.compareTo(y)>0?x:y;
    10     }
    11     public static void main(String[] args) {
    12         Integer[] arr = {1,2,3};//必须是包装类
    13         printArray(arr);
    14         System.out.println(max("B", "a"));
    15     }
    16     
    17 }

     六、问号通配符

    上代码

    1 public class WildCast {
    2 
    3     public static void main(String[] args) {
    4         Set<String> set = new HashSet<String>();//向上转型
    5         //HashSet<Object> set = new HashSet<String>();//编译出错Type mismatch,泛型Object和泛型String之间不存在继承关系
    6     }
    7 }

     在看下面代码:

     1 public class WildCast {
     2 
     3     public static void main(String[] args) {
     4         
     5         List<Integer> list = new ArrayList<>();
     6         list.add(11);
     7         print(list);//编译出错
     8         printNew(list);
     9     }
    10 
    11     private static void printNew(Collection<?> collection) {
    12         // TODO Auto-generated method stub
    13         collection.forEach(obj -> System.out.println(obj));
    14     }
    15 
    16     private static void print(Collection<Object> collection) {
    17         // TODO Auto-generated method stub
    18         collection.forEach(obj -> System.out.println(obj));
    19     }
    20 }

    泛型<Integer>和泛型<Object>没有继承关系,不能传递。所以使用通配符<?>

  • 相关阅读:
    HTML5实现音频播放
    百度编辑器UEditor常用设置函数大全
    .Net一般处理程序来实现用户名的验证
    软件设计师13-数据库设计
    软件设计师12-数据流图
    百度云BCC安装WordPress镜像
    Java获取客户端真实IP地址
    软件设计师11-面向对象技术
    百度云BCC主机宝镜像
    软件设计师10-系统开发模型
  • 原文地址:https://www.cnblogs.com/tomasman/p/6845910.html
Copyright © 2020-2023  润新知