【Java 你应该知道的】 泛型01

来源:互联网 发布:王者荣耀输入法软件 编辑:程序博客网 时间:2024/05/17 07:57

为什么使用泛型

        通过泛型可以定义类型安全的数据结构,而无须使用实际的数据类型,这能够显著提高性能并得到更高质量的代码。我们可以简单总结为“可扩展”,“更安全”。

        回忆一下Java中的集合,以List为例,如果使用时不指定泛型,存储的数据会被包装成Ojbect类型。从List中读取的数据也是装箱后的Object,使用前还需要通过强制类型转换拆箱成相应类型。这样做不仅效率低,还存在风险(强制类型转换错误)。

    // 定义集合未指定泛型    List datas = new ArrayList<>();    // 存储的数据会被保存成Object    datas.add("a1");    datas.add(123);    // 读取的数据也是Object,需要强制类型转换    for (Object obj : datas) {        String str = (String) obj; // 编译可通过,但运行异常        System.out.println(str);    }

上面的案例,会报异常异常,因为类型转换错误。

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String


泛型类

再看一个没有使用泛型的做法,定义一个简单的Box类。

    public class Box {        private String obj;        public Box(String obj) {            super();            this.obj = obj;        }        public String getObj() {            return obj;        }        public void setObj(String obj) {            this.obj = obj;        }       }

        上面的Box类里面现在只能装入String类型的元素,今后如果我们需要装入Integer等其他类型的元素,还必须要另外重写一个Box,代码得不到复用。如果将String改成Object,又会涉及类型转换的问题。很多初学者在封装工具类的时候,为了达到通用型,会采用Object的方式,其实这样做是不对的。

        泛型实JDK1.5提出的新特效,以上的问题可以采用泛型类的方式加以处理。泛型类的写法是在类名后面加上 <T> ,这里的T是泛型形参,可以代表任意的引用类型。使用该类的时候,必须指明具体的引用类型,即泛型实参。

    public class Box<T> {        private T t;        public Box(T t) {            super();            this.t = t;        }        public T getT() {            return t;        }        public void setT(T t) {            this.t = t;        }    }
    Box<String> box = new Box<String>("abc");    String obj = box.getT();    Box<Integer> box2 = new Box<Integer>(2);    Integer obj2 = box2.getT();

几点说明:

  • 泛型不支持基本数据类型,只能是引用类型
  • 泛型可以有多个,用逗号分隔,如<T,V>
  • 泛型形参可以使用T、E、K、V等形式,一般根据意义来选择
    • T: Type(类型)
    • E: Element (元素)
    • K: Key(键)
    • V: Value(值)
    • N: Number(数值类型)

泛型方法

泛型方法的实现方式也比较简单,只需要在方法返回类型前面加上泛型形参即可。 泛型方法使得该方法能独立于类而产生变化。如果使用泛型方法可以取代将整个类泛型化,那么建议只使用泛型方法。

    public static <T> void show(T t) {        System.out.println(t.toString());           }
    Utils.show("abc");    Utils.show(123);


泛型接口

        看到这里,我相信大家能大体理解了泛型的作用了。在实际开发中,泛型最多的应用场景应该是在接口中使用了,我们称为泛型接口。比如当我们定义Person类或者Animal类的使用,都有eat的动作,我们会把eat的行为抽象成接口。但吃什么不确定,这个时候就可以使用上泛型接口了。

    public interface IEatable<T> {        void eat(T t);      }
    public class Person implements IEatable<String>{        @Override        public void eat(String t) {            System.out.println("吃了" + t);           }    }
    public class Animal<T> implements IEatable<T>{        @Override        public void eat(T t) {            System.out.println("吃了" + t.toString());        }    }

点滴分享  共同进步



原创粉丝点击