本文主要讨论一下如何声明泛型类,讨论的范围涉及构造函数、静态成员、内部类。

构造函数

泛型的类型参数首先声明在首部:

public class Pair<T,U> {
    private final T first;
    private final U second;
    private static int count = 0;

    public Pair(T first, U second) {
        this.first = first;
        this.second = second;
    }

    public T getFirst() {
        return first;
    }

    public U getSecond() {
        return second;
    }

    public static void main(String[] args) {
        Pair<Integer,String> pair = new Pair<Integer,String>(2,"generic test");      // 1 line
        System.out.println(pair.getFirst());
        System.out.println(pair.getSecond());
    }
}

当我们调用构造函数时,真实的泛型参数将被传入,如代码中的“1 line”这行所示。

Pair<String, Integer> pair = new Pair("one",2);

构造函数也可以向上述这么写,但会提示warning。

甚至我们还可以这么写:

Pair pair = new Pair("one",2);

这个不会报错,也会提示warning。

静态成员

对于静态成员而言,是类可见的,所以

public class Cell<T> {
    private final int id;
    private final T value;
    private static int count = 0;
    private static synchronized int nextId() {
        return count++;
    }

    public Cell(T value) {
        this.value = value;
        id = nextId();
    }

    public T getValue() {
        return value;
    }

    public int getId() {
        return id;
    }

    public static synchronized int getCount() {
        return count;
    }
}

我们可以通过Cell.getCount()直接获取静态成员,并不需要指定类型参数。

如果指定类型参数反而报错:

Cell<Integer>.getCount()   // compile-time error

泛型类的静态成员及静态函数是对整个泛型类而言,因此固定类型参数的类进行调用:如Cell<Integer>.getCount()。

同样的,像下面这样的代码也是错误的:

class Cell2<T> {
private final T value;
private static List<T> values = new ArrayList<T>(); // illegal public Cell(T value) { this.value=value; values.add(value); } public T getValue() { return value; }
public static List<T> getValues() { return values; } // illegal
}

内部类

对非静态内部类而言,其外部类(outer class)的类型参数对它是可见的。因此内部类可以使用外部类的类型参数:

public class LinkedCollection<E> extends AbstractCollection<E> {
    private class Node {
        private E element;
        private Node next = null;
        private Node(E elt) { element = elt; }
    }
    ....
}

而对于静态内部类而言,则类型参数则是不可见的,我们必须自己定义内部类的类型参数:

class LinkedCollection<E> extends AbstractCollection<E> {
    private static class Node<T> {
        private T element;
        private Node<T> next = null;
        private Node(T elt) { element = elt; }
    }
}

我们在使用外部类中,使用内部类变量时,将外部类类型参数E传入内部类即可:

class LinkedCollection<E> extends AbstractCollection<E> {
    private static class Node<T> {
        ....
    }
    private Node<E> first = new Node<E>(null);
    private Node<E> last = first;
}

在软件工程中,比较推荐使用静态内部类,因为它不持有外部类的引用。因此静态内部类可以像类似外部类一样使用,更简单,更好理解。

tips:

如果内部类的的修饰符是public:

对非静态内部类而言,可以这么访问Node:LinkedCollection<E>.Node

而对静态内部类而言:LinkedCollection.Node<E>。

java泛型探索——泛型类的更多相关文章

  1. java泛型探索——介绍篇

    1. 泛型出现前后代码对比 先来看看泛型出现前,代码是这么写的: List words = new ArrayList(); words.add("Hello "); words. ...

  2. Java泛型:泛型类、泛型接口和泛型方法

    根据<Java编程思想 (第4版)>中的描述,泛型出现的动机在于: 有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一. ...

  3. Java泛型:泛型类,泛型接口和泛型方法

    转自: https://segmentfault.com/a/1190000002646193 泛型的产生很多缘由是因为 容器类  的创建 泛型类 容器类应该算得上最具重用性的类库之一.先来看一个没有 ...

  4. java泛型探索——小特性

    泛型特性(小篇幅) 1. 补充介绍一些常见的泛型特性: 类型参数T可以是recursive(类似递归性),它的边界可以是类型参数是自身的接口或类. 如我实现寻找最大值的方法,可以这么写: public ...

  5. java 泛型 -- 泛型类,泛型接口,泛型方法

    泛型T泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束.在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数.形式类型参数与实际类型参数之间的关系类似于形式方 ...

  6. java泛型应用实例 - 自定义泛型类,方法

    近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法, ...

  7. Java泛型总结

    1. 什么是泛型?泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的 ...

  8. java泛型详解(加一点语法糖)

    首先请看如下代码: public class Test{ public static void main(String str[]) { Hashtable h =new Hashtable(); h ...

  9. Java基础学习总结(83)——Java泛型总结

    1. 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型 ...

随机推荐

  1. linux系统使用python监测网络接口获取网络的输入输出

    #!/usr/bin/env Pythonimport timeimport sys if len(sys.argv) > 1: INTERFACE = sys.argv[1]else: INT ...

  2. Adobe 系列软件通用破解方式(animate cc,Photoshop cc,Flash cc)等

    破解之前准备工作: ①:安装好 试用版的 Adobe软件 ②:下载好破解软件: amtemu.v0.9.2-painter,下载地址:链接:http://pan.baidu.com/s/1nvNR74 ...

  3. [原]node.js使用感想

    最近尝试了使用node.js,但因为不是太深入(小项目,还没做完),所以不能谈心得谈经验,就来谈谈使用感想. node.js和以往的cgi接口的服务器+cgi程序(如apache+phpmod)中的单 ...

  4. poptest老李谈数据库优化总结

    poptest老李谈数据库优化总结   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:9088 ...

  5. 老李性能测试分享:可以没事代理刷榜赚外快了,poptest这是让你快速致富啊

    老李性能测试分享:可以没事代理刷榜赚外快了,poptest这是让你快速致富啊   最近学员不断面试,不时听到令人惊喜的消息,类似应届专科毕业生获得7k月薪,小美女应聘月薪11k等等,看到学员开心的笑容 ...

  6. Fragment深入解析

    写在顶部表示这点很重要:  本文转载自博客:http://blog.csdn.net/lmj623565791/article/details/37970961   欢迎访问原文 自从Fragment ...

  7. ReactJS入门3:组件的生命周期

    本文主要介绍组件的生命周期. 组建的生命周期主要分为3个:Mounting.Updating.Unmounting. 1. Mounting:组件被加载到DOM     在本阶段,主要有三个方法: 1 ...

  8. Android 学习笔记之实时保存数据-现场保护onSaveInstanceState()

    数据保存:在软件开发中我们希望保存下各个Activity数据,以实现客户数据的时时保存,达到较好的用户体验. 那么我们需要解决如下问题: 1.什么时候保存? 2.保存哪些数据?     我想保存应用产 ...

  9. Bar 3D 和Pie 3D的统计图形

    最近在做一个关于图形统计的界面,主要用到的是Dev控件ChartControl(功能很强大,能解决基本和复杂图形统计问题). ChartControl主要有Diagram.Series.Legend三 ...

  10. web开发与IC卡读卡器

    前段时间有个项目在客户端web下使用IC卡读卡器,试了很多种方案都觉得麻烦,最后在网上找了个现成的方案,采用了YW-605HA读卡器,厂家就不说了,免得说做广告.开发起来也挺简单. 他们将IC卡读卡器 ...