JAVA泛型的基本使用

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/beliefer/article/details/50763741 Java1.5版本推出了泛型,虽然这层语法糖给开发人员带来了代码复用性方面的提升,但是这不过是编译器所做的一层语法糖,在真正生成的字节码中,这类信息却被擦除了。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/beliefer/article/details/50763741

Java1.5版本推出了泛型,虽然这层语法糖给开发人员带来了代码复用性方面的提升,但是这不过是编译器所做的一层语法糖,在真正生成的字节码中,这类信息却被擦除了。笔者发现很多几年开发经验的程序员,依然不善于使用Java泛型,本文将从Java泛型的基本使用入手,在今后的多篇博文里,对泛型的使用做个总结。本文不会深入Java泛型的实现原理,只会介绍Java泛型的使用。

实验准备

  首先需要创建一个类继承体系。以商品为例,每种商品都有基本的名称属性。在大数据应用中,数据表和服务都可以作为商品,表有行数属性,服务有方法属性,实现如代码清单1所示。

代码清单1

class Auction {

    private String name;

    public Auction(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    public String toString() {
        return name;
    }

}

class Table extends Auction {
    
    private Integer rowNum;

    public Table(String name, Integer rowNum) {
        super(name);
        this.rowNum = rowNum;
    }

    public Integer getRowNum() {
        return rowNum;
    }

    public void setRowNum(Integer rowNum) {
        this.rowNum = rowNum;
    }
    
    public String toString() {
        return super.toString() + ", rowNum :" + rowNum;
    }
    
}

class Service extends Auction {

    private String method;
    
    public Service(String name, String method) {
        super(name);
        this.method = method;
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method;
    }
    
    public String toString() {
        return super.toString() + ", method :" + method;
    }
    
}

实验:泛型最基本使用

  现在为了演示泛型的使用,还是以商品为例。数据表本身只是Hbase中的一张表,而服务是运行于Hadoop Yarn之上的一个数据服务,比如说是Strom、Spark或者Oozie。无论是数据表还是服务,它本身并不是商品,要成为商品,必须有个装饰器将它包装为商品,现在我们用泛型实现一个简单的装饰器,见代码清单2所示。

代码清单2

class Decorator<T> {
    
    /**
     * 
     * 描 述:Exp1使用<br/>
     * 作 者:jiaan.gja<br/>
     * 历 史: (版本) 作者 时间 注释 <br/>
     * @param itemList
     */
    public void doDecorate(List<T> itemList) {
        for(int i = 0; i < itemList.size(); i++) {
            System.out.println(itemList.get(i));
        }
    }
    
    /**
     * 
     * 描 述:Exp1使用<br/>
     * 作 者:jiaan.gja<br/>
     * 历 史: (版本) 作者 时间 注释 <br/>
     * @param itemList
     * @param t
     */
    public void addDecorate(List<T> itemList, T t) {
        itemList.add(t);
    }
    
}

现在我们可以使用Decorator给List添加或者打印任何类型了,如代码清单3所示。

代码清单3

/**
 * 
 * 类 名: Exp1<br/>
 * 描 述: 泛型最基本使用<br/>
 * 作 者: jiaan.gja<br/>
 * 创 建: 2015年8月13日<br/>
 *
 * 历 史: (版本) 作者 时间 注释
 */
class Exp1 {
    public static void main(String[] args) {

        Decorator<Auction> decoratorA = new Decorator<Auction>();
        List<Auction> listA = new ArrayList<Auction>();
        Auction auctionOne = new Auction("auctionOne");
        Auction auctionTwo = new Auction("auctionTwo");
        decoratorA.addDecorate(listA, auctionOne);
        decoratorA.addDecorate(listA, auctionTwo);
        decoratorA.doDecorate(listA);
        
        Decorator<Table> decoratorB = new Decorator<Table>();
        List<Table> listB = new ArrayList<Table>();
        Table tableOne = new Table("tableOne", 10);
        Table tableTwo = new Table("tableTwo", 20);
        decoratorB.addDecorate(listB, tableOne);
        decoratorB.addDecorate(listB, tableTwo);
        decoratorB.doDecorate(listB);
        
        Decorator<Service> decoratorC = new Decorator<Service>();
        List<Service> listC = new ArrayList<Service>();
        Service serviceOne = new Service("serviceOne", "methodOne");
        Service serviceTwo = new Service("serviceTwo", "methodTwo");
        decoratorC.addDecorate(listC, serviceOne);
        decoratorC.addDecorate(listC, serviceTwo);
        decoratorC.doDecorate(listC);
        
    }
}

遗留问题

如果想要Auction用于Decorator,必须要声明Decorator<Auction>;Service用于Decorator,也必须声明Decorator<Service>。由于Table是Auction的子类型,我们自然想将Table也能用于Decorator<Auction>,就像下面这样:

decoratorA.doDecorate(listB);


listB的泛型Table的确是decoratorA的泛型Auction的子类型,但是编译器会报错,说明不允许这种语法。

如何解决这个问题?请看下一篇 《Java泛型的协变》

相关文章
|
3月前
|
安全 Java 编译器
揭秘JAVA深渊:那些让你头大的最晦涩知识点,从泛型迷思到并发陷阱,你敢挑战吗?
【8月更文挑战第22天】Java中的难点常隐藏在其高级特性中,如泛型与类型擦除、并发编程中的内存可见性及指令重排,以及反射与动态代理等。这些特性虽强大却也晦涩,要求开发者深入理解JVM运作机制及计算机底层细节。例如,泛型在编译时检查类型以增强安全性,但在运行时因类型擦除而丢失类型信息,可能导致类型安全问题。并发编程中,内存可见性和指令重排对同步机制提出更高要求,不当处理会导致数据不一致。反射与动态代理虽提供运行时行为定制能力,但也增加了复杂度和性能开销。掌握这些知识需深厚的技术底蕴和实践经验。
75 2
|
13天前
|
Java API
[Java]泛型
本文详细介绍了Java泛型的相关概念和使用方法,包括类型判断、继承泛型类或实现泛型接口、泛型通配符、泛型方法、泛型上下边界、静态方法中使用泛型等内容。作者通过多个示例和测试代码,深入浅出地解释了泛型的原理和应用场景,帮助读者更好地理解和掌握Java泛型的使用技巧。文章还探讨了一些常见的疑惑和误区,如泛型擦除和基本数据类型数组的使用限制。最后,作者强调了泛型在实际开发中的重要性和应用价值。
12 0
[Java]泛型
|
22天前
|
存储 安全 Java
🌱Java零基础 - 泛型详解
【10月更文挑战第7天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
10 1
|
29天前
|
Java 语音技术 容器
java数据结构泛型
java数据结构泛型
26 5
|
27天前
|
存储 Java 编译器
Java集合定义其泛型
Java集合定义其泛型
17 1
|
2月前
|
Java 编译器 容器
Java——包装类和泛型
包装类是Java中一种特殊类,用于将基本数据类型(如 `int`、`double`、`char` 等)封装成对象。这样做可以利用对象的特性和方法。Java 提供了八种基本数据类型的包装类:`Integer` (`int`)、`Double` (`double`)、`Byte` (`byte`)、`Short` (`short`)、`Long` (`long`)、`Float` (`float`)、`Character` (`char`) 和 `Boolean` (`boolean`)。包装类可以通过 `valueOf()` 方法或自动装箱/拆箱机制创建。
34 9
Java——包装类和泛型
|
29天前
|
存储 Java 编译器
【用Java学习数据结构系列】初识泛型
【用Java学习数据结构系列】初识泛型
18 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
27天前
|
安全 Java 编译器
Java基础-泛型机制
Java基础-泛型机制
13 0
|
2月前
|
存储 安全 搜索推荐
Java中的泛型
【9月更文挑战第15天】在 Java 中,泛型是一种编译时类型检查机制,通过使用类型参数提升代码的安全性和重用性。其主要作用包括类型安全,避免运行时类型转换错误,以及代码重用,允许编写通用逻辑。泛型通过尖括号 `&lt;&gt;` 定义类型参数,并支持上界和下界限定,以及无界和有界通配符。使用泛型需注意类型擦除、无法创建泛型数组及基本数据类型的限制。泛型显著提高了代码的安全性和灵活性。