前面提到的都是与类的泛型化相关的话题,不过方法也可以从泛型中受益,尤其是Helper类的工具方法这种"无状态"的方法更加合适。还是有几个话题可以进一步讨论下的。
1. 类型推导
所谓类型推导,就是编译器可以通过判断参数的类型来推导类型参数(泛型)的类型。这句话初看会发现非常绕口,举个例子就能很好的理解了。
这个方法的目的是将set1和set2的元素进行合并。在使用这个方法的时候,如果传入的参数是Set<Integer>类型的,那么编译器就会自动推导出E的类型是Integer了。
这个特性可以使用在一种叫做"泛型静态工厂方法"的的编写上,比如下面的几个方法。
这里的一系列方法就是运用了类型推导的来使Map和Set的创建语句缩短,程序员都应该是懒人吗!呵呵。
这里,对于类型推导,还有一个比较重要的用法,就是"泛型单例工厂"。举个例子如下:
假设有一个如下的接口:
这个接口可以对Number的子类进行封装,它提供了一个方法可以输出值的平方。对于这样的Wrapper,我并不想对于每一个T都实例化一个相应的对象,那样有一些浪费,这时,就可以使用这个泛型单例工厂来生成支持不同T的单例。另外,因为NumberWrapper的泛型信息在运行时是会被擦除的,所以也没有必要对每一个T生成一个实例。泛型单例工厂的代码如下:
这里,有一个点要注意下,就是getWrapperInstance()方法的的类型转换,这里是一个NumberWrapper<Number>向NumberWrapper<T>的转换,这里,由于square()方法返回的仅仅是平方,这里是不会导致类型错误的,所以可以放心的禁止这条警告了。
程序的运行结果如下所示:
4.0
0.0025000000000000005
说明程序还是运行良好的。
2. 递归类型限制
所谓递归类型限制,是使用包含某个参数类型本身的表达式去限制参数的类型。比如java.util.Collections的max()方法,定义如下:
这里面的具体实现先不用去关注。这里,类型参数的定义是T extends Object & Comparable<? super T>。T是要扩展自Comparable<? super T>的,这里就是一个递归类型限制。其实也好理解,比如String类就是Comparable<String>的子类,Integer是Comparable<Integer>的子类,只有类型是"可以比较的"才能去计算的最大值吗。
这个的用法不多,就不去仔细研究了,到真正会使用的时候再去研究也不晚,这就是所谓的"延迟加载"吧,呵呵。
1. 类型推导
所谓类型推导,就是编译器可以通过判断参数的类型来推导类型参数(泛型)的类型。这句话初看会发现非常绕口,举个例子就能很好的理解了。
Java代码
public class GenericHelper { public static <E> Set<E> merge(Set<E> set1, Set<E> set2){ Set<E> retSet = new HashSet<E>(set1); retSet.addAll(set2); return retSet; } }
这个方法的目的是将set1和set2的元素进行合并。在使用这个方法的时候,如果传入的参数是Set<Integer>类型的,那么编译器就会自动推导出E的类型是Integer了。
这个特性可以使用在一种叫做"泛型静态工厂方法"的的编写上,比如下面的几个方法。
Java代码
public static <E> Set<E> createSet() { return new HashSet<E>(); } public static <K, V> Map<K, Set<V>> createMap() { return new HashMap<K, Set<V>>(); } public static void main(String[] args) { Map<String, Set<Integer>> str = createMap(); Set<Integer> set = createSet(); str.put("key", set); }
这里的一系列方法就是运用了类型推导的来使Map和Set的创建语句缩短,程序员都应该是懒人吗!呵呵。
这里,对于类型推导,还有一个比较重要的用法,就是"泛型单例工厂"。举个例子如下:
假设有一个如下的接口:
Java代码
public interface NumberWrapper<T extends Number> { public double square(T num); }
这个接口可以对Number的子类进行封装,它提供了一个方法可以输出值的平方。对于这样的Wrapper,我并不想对于每一个T都实例化一个相应的对象,那样有一些浪费,这时,就可以使用这个泛型单例工厂来生成支持不同T的单例。另外,因为NumberWrapper的泛型信息在运行时是会被擦除的,所以也没有必要对每一个T生成一个实例。泛型单例工厂的代码如下:
Java代码
public class GenericFactory { private static NumberWrapper<Number> numWrapper = new NumberWrapper<Number>() { @Override public double square(Number num) { return num.doubleValue() * num.doubleValue(); } }; @SuppressWarnings("unchecked") public static <T extends Number> NumberWrapper<T> getWrapperInstance() { return (NumberWrapper<T>) numWrapper; } public static void main(String[] args) { NumberWrapper<Integer> integerWrapper = GenericFactory.getWrapperInstance(); System.out.println(integerWrapper.square(2)); NumberWrapper<Double> doubleWrapper = GenericFactory.getWrapperInstance(); System.out.println(doubleWrapper.square(0.05)); } }
这里,有一个点要注意下,就是getWrapperInstance()方法的的类型转换,这里是一个NumberWrapper<Number>向NumberWrapper<T>的转换,这里,由于square()方法返回的仅仅是平方,这里是不会导致类型错误的,所以可以放心的禁止这条警告了。
程序的运行结果如下所示:
4.0
0.0025000000000000005
说明程序还是运行良好的。
2. 递归类型限制
所谓递归类型限制,是使用包含某个参数类型本身的表达式去限制参数的类型。比如java.util.Collections的max()方法,定义如下:
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) { Iterator<? extends T> i = coll.iterator(); T candidate = i.next(); while (i.hasNext()) { T next = i.next(); if (next.compareTo(candidate) > 0) candidate = next; } return candidate; }
这里面的具体实现先不用去关注。这里,类型参数的定义是T extends Object & Comparable<? super T>。T是要扩展自Comparable<? super T>的,这里就是一个递归类型限制。其实也好理解,比如String类就是Comparable<String>的子类,Integer是Comparable<Integer>的子类,只有类型是"可以比较的"才能去计算的最大值吗。
这个的用法不多,就不去仔细研究了,到真正会使用的时候再去研究也不晚,这就是所谓的"延迟加载"吧,呵呵。
发表评论
-
网络游戏同步的原理
2011-09-22 20:01 817不知道大家是否碰到过这种情况,当某个玩家发出一个火球,这个火球 ... -
java中的io系统详解
2010-09-16 23:21 885Java 流在处理上分为字符流和字节流。字符流处理的单元为 ... -
java中的日期处理类总结
2010-08-08 20:35 858java中的日期处理类总结:Date/Calendar/Gre ... -
体验J2SE 1.5新特性之增强For循环
2010-04-08 14:49 824J2SE 1.5提供了另一种形 ... -
XPath
2010-03-22 17:52 1622XPath 简介 XPath 是一门 ... -
通过Singleton单例模式,理解Java的类加载
2010-03-22 16:26 1104通过Singleton单例模式,理解Java的类加载----- ... -
全面总结Java泛型
2009-10-25 12:19 761虽然Scala创始人Martin Odersky说当年正是因为 ... -
理解java String
2009-10-20 15:07 612要理解 java中String的运 ... -
字符串相关
2009-10-20 15:06 588Java代码 public class St ... -
Java中"equals"和"=="的区别
2009-10-20 14:01 658一句话概括:==比较的 ... -
Java代码编写的30条建议
2009-05-14 22:21 746(1) 类名首字母应该大写。字段、方法以及对象(句柄)的首字母 ... -
深入了解Java泛型(二) -- 泛型列表与数组
2009-05-07 09:48 1020记得以前面试的时候曾 ... -
深入了解Java泛型(一) -- 泛型与原生态类型
2009-05-07 09:45 1221Java1.5引入了泛型之后, ... -
正则表达式入门
2009-05-07 09:16 611元字符: /b 代表着单词 ...
相关推荐
标题与描述均提到了“全面总结Java泛型--实例”,这表明文章旨在深入解析Java泛型的概念,并通过具体示例来展示其应用。Java泛型是Java编程语言的一个强大特性,它允许在编译时检查类型安全,并且所有的强制转换都是...
下面我们将深入探讨Java泛型方法的概念、语法以及使用示例。 **一、泛型方法概念** 泛型方法是一种具有类型参数的方法,这些类型参数可以在方法声明时指定,并在方法体内部使用。与类的泛型类似,它们提供了编译时...
Java泛型深入的内容涵盖泛型的基本概念、泛型类、接口、方法以及泛型的使用限制和高级特性。 首先,Java中的泛型允许定义方法、接口、类和变量时不指定具体的数据类型,而是在使用的时候再通过泛型类型参数来指定...
Java泛型是Java编程语言中的一个强大特性,它允许我们在定义类、接口和方法时指定类型参数,从而实现代码的重用和类型安全。在Java泛型应用实例中,我们可以看到泛型如何帮助我们提高代码的灵活性和效率,减少运行时...
本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展历程** - **早期版本的局限**:在Java泛型出现之前,程序员通常使用Object作为容器类(如ArrayList、HashMap等)的默认类型...
"Java 泛型学习" Java 泛型是 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的...
由于书籍的作者是Maurice Naftalin和Philip Wadler,这两人都是在泛型和集合方面有着深入研究的专家,因此书中内容被期待会是权威和详尽的,为读者提供全面的Java泛型和集合知识。本书适合有一定Java基础并希望深入...
### Java泛型的使用详细讲解 #### 一、引言 在Java开发中,泛型是一种重要的语言特性,它能够帮助开发者在不增加代码量的情况下处理多种数据类型,同时还能保持代码的清晰度和可读性。本文将详细介绍Java泛型的...
Java泛型是Java编程语言中的一个强大特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。这使得代码更加安全、可读性更强,并且能够减少类型转换的必要。在“java泛型的内部原理及更深应用”这个...
本篇文章将深入探讨Java泛型的发展历程、核心概念以及其在实际开发中的应用。 1. **发展历程** Java泛型的引入是为了解决早期版本中类型转换频繁和潜在的ClassCastException问题。在Java泛型出现之前,集合框架...
本篇文章将带你入门Java泛型,通过实例深入理解其核心概念。 1. **泛型的基本概念** - 泛型是一种允许在定义类、接口和方法时使用类型参数的机制。这使得代码可以在编译时期检查类型,避免了不必要的类型转换,并...
SUN公司的Java泛型编程文档,包括英文原版和网络翻译版,为开发者提供了深入理解和熟练运用泛型的重要资源。 首先,泛型的基本概念是允许在定义类、接口和方法时使用类型参数,这样就可以在编译时检查类型安全,...
java泛型详细学习,深入学习java的不二之选
在这个“泛型实例<匿名方法实现排序与查找>”中,我们将深入探讨如何利用泛型以及匿名方法来实现数据的排序和查找功能,这在S2学期的学习中是非常关键的实践环节。 首先,让我们理解什么是泛型。泛型是在.NET框架中...
本文将深入探讨C#和Java在泛型实现上的异同,帮助开发者更好地理解和利用这两种语言的泛型功能。 首先,我们来看C#中的泛型。C#自2.0版本开始引入泛型,它允许开发者在类、接口和方法中定义类型参数,从而创建可...
在本文中,我们将深入探讨Java泛型的进阶概念,包括通配符、边界、类型擦除以及在实际开发中的应用。 1. 通配符 通配符在Java泛型中扮演着重要角色,它允许我们处理多种类型的参数。例如,`<?>` 表示未知类型,...
在本教程中,我们将深入探讨Java泛型的源码实现,特别是"Java-Generics-Our-Generics-Class-Part-3-Source-code"项目中的部分。 首先,泛型的主要目标是消除运行时类型转换异常,例如`ClassCastException`。通过在...