`
notesth
  • 浏览: 9425 次
社区版块
存档分类
最新评论

Java的Generic Programming简介

阅读更多
下面是自己学习Java的generic programming后的一点总结,以供大家尽快地对其有一个大概的了解。

文章的思路是:1. 定义;2. 原理;3. 通配符(wildcard types)

1. 定义

什么是generic programming?在定义class,interface和method的时候,generics可以把class或者是interface当成一个类型参数。参考的是http://docs.oracle.com/javase/tutorial/java/generics/why.html

首先看怎么定义一个generic class,举个代码例子,这样更直观一点。



public class Pair<T>
{
	public Pair() { first = null; second = null; }
	public Pair(T first, T second) { this.first = first; this.second = second; }
	public T getFirst() { return first; }
	public T getSecond() { return second; }
	public void setFirst(T newValue) { first = newValue; }
	public void setSecond(T newValue) { second = newValue; }
	private T first;
	private T second;
	
	public static void main(String[] args){
		Pair<Integer> integerPair = new Pair(0, 1);
		Pair<String> stringPair = new Pair("thinking in java", "java core");
		...
	}
}



然后看下怎么定义generic method,还是看代码。

class ArrayAlg
{
public static  T getMiddle(T[] a)
{
return a[a.length / 2];
}
}



到此,定义类和方法的具体写法就介绍完了,下面也很容易想到对于参数类型“T”有没有什么限制呢?下面就介绍“T”的使用限制范围(Bounds of Type Variable)。

可以定义代码:

public static <T extends Comparable>  Pair minmax(T[] a)...



其中Comparable就是T的bounding type,实际就是T的一个继承关系中的限制条件了。注意,这个概念很重要,在之后介绍generics在虚拟机中怎么运行的时候会提及。

2. 原理

也就是介绍generics在虚拟机中是什么样的。

在虚拟机中,所有的类或者是接口都必须有一个类型,那“T”的类型是什么呢?答案自然不是“T”,而是在定义了generic type之后,虚拟机会自动提供一个raw type。

那什么又是raw type?他不是一个具体的类或者是接口,而是定义generics的所有的T的bounding type的总称,按语法来讲,他不是个名词,而是个代词。

比如最开始的例子,Pair<T>,其的raw type就是Object,而...<T extends Comparable>...的raw type就是Comparable。

在虚拟机中,第一个Pair<T>例子的代码就会变成:

public class Pair
{
public Pair(Object first, Object second)
{
this.first = first;
this.second = second;
}
public Object getFirst() { return first; }
public Object getSecond() { return second; }
public void setFirst(Object newValue) { first = newValue; }
public void setSecond(Object newValue) { second = newValue; }
private Object first;
private Object second;

...
}


那经过转化之后,“T”已经不是原来的那个“T”了,但是为什么Pair<Integer>(当然Pair<String>同理)还是原来的Pair<Integer>呢?

因为编译器会在把值取出来之前再强制转化类型。

即,generics在虚拟机里的过程是:

  • 存,存成bounding type类型的
  • 取,把bounding type类型的东西再还原回来


这个过程非常重要,很多地方都是拿这个过程解释的,当然,也有一部分冲突是由此引起的。

下面就介绍一个由于此过程引起的冲突以及由此引出的一个概念,bridge method。

看如下代码,注意这段代码是合法的:

class DateInterval extends Pair<Date>
{
public void setSecond(Date second)
{
if (second.compareTo(getFirst()) >= 0)
super.setSecond(second);
}
. . .
}


因为DateInterval是继承Pair<Date>,自然继承了Pair<Date>的setSecond方法,但是由于在虚拟机中Pair<Date>的setSecond方法被存为

public void setSecond(Object second)
{
...
}


即相当于在DateInterval中有两个名字相同,参数不同(但是注意参数有继承关系)的方法,如果要调用setSecond就不知所措了,下图阴影部分为继承Pair<Date>所得,仅为示例之用。


这时候编译器会提供一个bridge method,来解决两个方法冲突的问题。

public void setSecond(Object second) { setSecond((Date) second); }


这样问题就得到解决了,注意,这里是编译器的事儿,与写代码无关。

在原理部分需要注意的几点是
  • 实际上是没有generics存在的,也就是上面的“T”
  • 所有的type parameters都会换成他们的bounding type
  • bridge method会解决冲突的问题
  • 在虚拟机里面会执行类型转换以确保安全


3. 通配符(wildcard types)

也就是在使用generics的时候嫌麻烦,可以使得generic type中的type parameter可以在继承关系上使用更灵活点,或者是可以使用type parameter的父类,或者是可以使用其的子类。

比如在方法:

public static void printBuddies(Pair<Employee> p)
{
Employee first = p.getFirst();
Employee second = p.getSecond();
System.out.println(first.getName() + " and " + second.getName() + " are buddies.";
}


其中要想给printBuddies传递一个Pair<Manager>类型的参数是不合法的,于是乎产生了一种新的定义方法:

public static void printBuddies(Pair<? extends Employee> p)


这样,就可以把Pair<Manager>类型的参数传入方法了。同理还可以定义代码:

public static void printBuddies(Pair<? super Manager> p)


这样的意思就变成所有Manager的父类都可以调用此段代码了。

最后也可以就通配符“?”一个,什么继承关系都没有,比如:

public static void printBuddies(Pair<?> p)


具体通配符的用法可以参考http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html

没有介绍的太详细,但求大概能对generics有一个整体印象。

参考资料
  • 描述: DateInterval
  • 大小: 9.4 KB
2
2
分享到:
评论

相关推荐

    Generic Programming for Scientific Computing in C++, Java, and C#

    #### 泛型编程简介 - **定义**:泛型编程是一种允许编写可重用代码的技术,这些代码可以用于多种数据类型而不必为每种类型重复编写。在C++中,通过模板来实现泛型编程;而在Java和C#中,则是通过泛型(generics)来...

    generic programming.pdf

    泛型编程(Generic Programming)作为一种编程范式,其核心在于设计出可重用且高效的算法集合。它不仅仅局限于特定的数据类型,而是通过参数化类型的方式使得同一段代码可以处理多种数据结构。这种能力在现代软件...

    Generic in java programming language

    ### Java泛型编程详解 #### 引言 Java 5引入了多项语言级别的扩展功能,其中最为重要的一项就是泛型(Generics)的引入。本文档旨在为读者介绍Java中的泛型概念及其用法。 如果你熟悉其他语言如C++中的模板...

    Generics_in_the_Java_Programming_Language译文

    Java 泛型详解 Java 中的泛型是 Java 5(JDK 1.5)中引入的一项新特性,旨在解决类型安全和代码重用的问题。泛型允许程序员对类型进行抽象,使得代码更加灵活和可维护。 泛型的优点: 1. 类型安全:泛型可以在...

    Addison.Wesley.The.Java.Programming.Language.4th.Edition.Aug.2005.chm

    This book teaches the Java programming language to people who are familiar with basic programming concepts. It explains the language without being arduously formal or complete. This book is not an ...

    A.Field.Guide.to.Generic.Programming

    《A Field Guide to Generic Programming》是一本深入探讨泛型编程的指南,旨在帮助开发者更好地理解和应用这一编程范式。泛型编程是现代编程语言中一个关键的概念,它允许程序员创建可重用的数据结构和算法,这些...

    19-Generic-Programming-in-Java.ppt

    Java泛型编程是Java语言中一个重要的特性,它在Java SE 5.0版本中被引入,极大地提高了代码的类型安全性和重用性。泛型允许开发者在类、接口和方法中定义类型参数,从而创建可以操作多种数据类型的代码。在讲解泛型...

    Core Java Volume II 最新第8版 part1全两卷 (附随书源码)

    * Generic programming * The collections framework * Concurrency For detailed coverage of XML processing, networking, databases, internationalization, security, advanced AWT/Swing, and other ...

    Advanced-Java-Programming-by-Example:示例高级Java编程

    在Java编程领域,"Advanced Java Programming by Example" 是一个深入探讨高级Java特性的主题,它涵盖了通用类、通用接口和通用方法等核心概念。这些概念是Java编程中的关键要素,对于提升代码的可复用性、灵活性和...

    Generics_in_the_Java_Programming_Language.pdf

    在Java编程语言中,泛型是一种引入类型参数的概念,它允许程序员在使用类、接口和方法时编写与数据类型无关的代码,然后在创建对象或调用方法时明确指定这些类型。Java的泛型在JDK 1.5版本中被引入,并且它的出现极...

    JAVA核心技术卷一卷二(中文)之part2分卷

    Chapter 7 Exceptions, Logging, Assertions, and Debugging(新增批注共38条) Chapter 8 Generic Programming(新增批注共22条) Chapter 9 Collections(新增批注共55条) Chapter 10 Multithreading(新增批注共...

    Core Java. Volume I. Fundamentals, 8th Edition JAVA核心技术1基础知识

    12 GENERIC PROGRAMMING 13 COLLECTIONS 14 MULTITHREADING 第1章 Java 程序设计概述 1.1 Java 程序设计平台 1.2 Java 白皮书的关键术语 1.2.1 简单性 1.2.2 面向对象 1.2.3 网络技能 1.2.4 健壮性 1.2.5 安全性 ...

    JAVA核心技术卷一卷二(中文)之part4分卷

    Chapter 7 Exceptions, Logging, Assertions, and Debugging(新增批注共38条) Chapter 8 Generic Programming(新增批注共22条) Chapter 9 Collections(新增批注共55条) Chapter 10 Multithreading(新增批注共...

    Core Java 9th Edition(Vol1,Vol2)

    Generic Programming Chapter 13. Collections Chapter 14. Multithreading Appendix A. Java Keywords Volume I: Streams and Files Networking Database programming XML JNDI and LDAP ...

    Java2核心技术卷I+卷2:基础知识(第8版) 代码

    Java As a Programming Platform 2 The Java “White Paper” Buzzwords 2 Java Applets and the Internet 7 A Short History of Java 9 Common Misconceptions about Java 11 Chapter 2: The Java ...

    JAVA核心技术卷一卷二(中文)之part3分卷

    Chapter 7 Exceptions, Logging, Assertions, and Debugging(新增批注共38条) Chapter 8 Generic Programming(新增批注共22条) Chapter 9 Collections(新增批注共55条) Chapter 10 Multithreading(新增批注共...

    JAVA核心技术卷一卷二(中文)之part1分卷

    Chapter 7 Exceptions, Logging, Assertions, and Debugging(新增批注共38条) Chapter 8 Generic Programming(新增批注共22条) Chapter 9 Collections(新增批注共55条) Chapter 10 Multithreading(新增批注共...

Global site tag (gtag.js) - Google Analytics