java泛型探索——泛型类
本文主要讨论一下如何声明泛型类,讨论的范围涉及构造函数、静态成员、内部类。
构造函数
泛型的类型参数首先声明在首部:
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泛型探索——泛型类的更多相关文章
- java泛型探索——介绍篇
1. 泛型出现前后代码对比 先来看看泛型出现前,代码是这么写的: List words = new ArrayList(); words.add("Hello "); words. ...
- Java泛型:泛型类、泛型接口和泛型方法
根据<Java编程思想 (第4版)>中的描述,泛型出现的动机在于: 有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类. 泛型类 容器类应该算得上最具重用性的类库之一. ...
- Java泛型:泛型类,泛型接口和泛型方法
转自: https://segmentfault.com/a/1190000002646193 泛型的产生很多缘由是因为 容器类 的创建 泛型类 容器类应该算得上最具重用性的类库之一.先来看一个没有 ...
- java泛型探索——小特性
泛型特性(小篇幅) 1. 补充介绍一些常见的泛型特性: 类型参数T可以是recursive(类似递归性),它的边界可以是类型参数是自身的接口或类. 如我实现寻找最大值的方法,可以这么写: public ...
- java 泛型 -- 泛型类,泛型接口,泛型方法
泛型T泛型的许多最佳例子都来自集合框架,因为泛型让您在保存在集合中的元素上指定类型约束.在定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数.形式类型参数与实际类型参数之间的关系类似于形式方 ...
- java泛型应用实例 - 自定义泛型类,方法
近 短时间需要使用泛型,就研究了下,发现网上的问关于泛型的文章都是讲原理的, 很少有提到那里用泛型比较合适, 本文就泛型类和泛型方法的使用给出两 个典型应用场景. 例如一个toString的泛型方法, ...
- Java泛型总结
1. 什么是泛型?泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的 ...
- java泛型详解(加一点语法糖)
首先请看如下代码: public class Test{ public static void main(String str[]) { Hashtable h =new Hashtable(); h ...
- Java基础学习总结(83)——Java泛型总结
1. 什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型 ...
随机推荐
- Memcache存储机制与指令汇总
1.memcache基本简介 memcached是高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度.提高可扩展性. Memcach ...
- 第5章Zabbix自动化监控
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; text-align: justify; t ...
- 深入分析Java单例模式的各种方案
单例模式 Java内存模型的抽象示意图: 所有单例模式都有一个共性,那就是这个类没有自己的状态.也就是说无论这个类有多少个实例,都是一样的:然后除此者外更重要的是,这个类如果有两个或两个以上的实例的话 ...
- java调试技能之dubbo调试 ---telnet
dubbo作为一个远程调用框架,虽与同类型的框架,不知道谁优谁劣,但是就公司层面使用来说,还是很棒的.这里简单的写一下怎么使用和调试技巧,就算是作个使用总结吧,供快速使用和问题解决! dubbo是基于 ...
- 原生tab切换
<html><head><meta http-equiv="Content-Type" content="text/html; charse ...
- lumen 中的 .env 配置文件简介和适用场景
lumen 是 laravel 的衍生品,核心功能的使用和 laravel 都是一致的,但配置文件这一方面,lumen 在 laravel 的基础上增加了更简便的配置方式: lumen 采用了 Dot ...
- 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控
如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...
- JavaScript基础学习(七)—BOM
BOM(Browser Object Model): 浏览器对象模型.提供了独立于内容而与浏览器窗口交互的对象,BOM主要用于管理窗口和窗口之间的通讯. 一.Navigator对象 ...
- 移动端WEBAPP开发遇到的坑,以及填坑方案!持续更新~~~~
前言:在移动端WEBAPP开发中会遇到各种各样的问题,通过此文对遇到的问题做一个归纳总结,方便自己日后查询,也给各位前端开发友人做一个参考. 此文中涉及的问题是本人开发中遇到的,解决方案是本人思考 ...
- 【one day one linux】find 用法详解小记
find命令的功能很强大,查找文件的选项很多,所以这是一个很实用并且很常用的linux命令.但是他有个缺点就是搜索的时候比较慢的.而与之相对的有一个locate命令. find的命令格式 find ...