• Java:泛型(一)


    泛型

    泛型是实现代码复用的重要手段,在Java集合类框架中泛型被广泛应用,本文介绍Java中泛型的概念及基本使用。

    泛型作用于编译前的静态类型检查,也就是说运行时JVM中实际上是没有泛型这种东西的,因为在运行前会进行类型擦除。泛型的使用让Java代码的复用变得方便,安全,规范,使静态类型检查在Object对象上也有了用武之地(使静态类型检查更有用处)


    泛型类

    我们有这样一个类

    public class Box{
    	public String object;
    	public void set(String object){this.object = object;}
    	public String get(){return object;}
    }
    

    这是一个简单的容器类,现在我们可以把String类的对象放入,取出,
    但如果我需要其他类型的容器,又要重写一个Box类,于是有了下面的容器类

    public class Box{
    	public Object object;
    	public void set(Object object){this.object = object;}
    	public Object get(){return object;}
    }
    

    上面这个代码基本上满足需求,但是如果不做标识,我们无法区分当前容器中装的到底是什么类型的对象,给取出数据后的转型带来麻烦,各种没有关系的对象都能放入一个集合,为了规范化,在Java1.5后,我们使用泛型

    public class Box<T>{
    	public T object;
    	public void set(T object){this.object = object;}
    	public T get(){return object;}
    }
    

    其中 T 是一个标志符,表示一种Type,写在类上的泛型T说明类中所有的T都表示同一类型,及作用域在整个类上
    通过泛型,Box类得到了复用,我们可以制造存放各种对象的Box

    Box<Integer> integerBox = new Box<Integer>();
    Box<String>  stringBox = new Box<>();这里可以看出,已知的泛型类型是可以省略不写的,IDEA中也默认隐藏
    Box objectBox = new Box();
    

    注意,假设 Teacher 类与 Student 类继承于 Person 类,由于Java的泛型实现机制,并不存在Box<Teacher>、Box<Student>、Box<Person>类型,因此Box<Teacher>、Box<Student>类型的变量与Box<Person>的变量之间不具有继承关系
    参见Java:泛型中的类型擦除


    泛型接口

    接口是一种特殊的类,所以泛型在接口中的应用参考泛型类(这一条就这样水过去了


    泛型方法

    定义了自己的泛型类型的方法才叫泛型方法
    同样,定义在方法上的泛型类型,作用域也只在该方法上
    仅仅使用类上的泛型的方法不称为泛型方法

    public class Pair<K,V>{
        private K key;
        private V value;
    
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
    
        public K getKey() { return key; }
    
        public void setKey(K key) { this.key = key; }
    
        public V getValue() { return value; }
    
        public void setValue(V value) { this.value = value; }
    
        public  boolean isEqual(Pair<K,V> p){
            return this.key == p.key && this.value == p.value;
        }
    }
    

    上面的这个isEqual方法中的K,V访问的是类上的泛型,所以下图产生编译期异常
    如图
    因为调用者p1的类型在静态类型检查中为Pair<Integer, String>,所以p1.isEqual接受的参数只能是Pair<Integer, String>,是不通用的,这也是使用类上定义的泛型的方法不称为泛型方法的原因,因为这种"泛型"是被类上的泛型固定住的类型,随着调用对象的泛型类型的改变而改变,属于类泛型的范畴

    所以泛型方法应当这样定义
    [作用域修饰符] <泛型类型标识> [返回类型] 方法名称(参数列表){}
    其实就是在返回值类型前加上泛型类型说明

    public <U,T> boolean isEqual(Pair<U,T> p){
            return this.key == p.key && this.value == p.value;
    }
    

    为了区分,这里用U、T作为该泛型方法的泛型名称。ps:泛型类型定义与变量一样,后定义的变量会隐藏先前定义的作用域更大的同名变量
    在这里插入图片描述
    可以看到报错已经消失
    在这里插入图片描述
    可以在这里添上正确的泛型标识,IDEA默认隐藏,是否写出看个人喜好,因为即使忘记方法使用了泛型,静态类型检查也会提示我们

    请移步 Java:泛型(二)


    2018/11/25

  • 相关阅读:
    使用 Anthem.NET 的经验小结
    使用 Anthem.NET 的常见回调(Callback)处理方式小结
    Anthem.NET 的回调流程图
    客户端调用服务器端方法——ASP.NET AJAX(Atlas)、Anthem.NET和Ajax.NET Professional实现之小小比较
    ASP.NET AJAX(Atlas)和Anthem.NET——管中窥豹般小小比较
    使用Anthem.NET 1.5中的FileUpload控件实现Ajax方式的文件上传
    Access中一句查询代码实现Excel数据导入导出
    Access中复制表
    tensorflow kmeans 聚类
    tensorflow knn mnist
  • 原文地址:https://www.cnblogs.com/kafm/p/12721835.html
Copyright © 2020-2023  润新知