这可以返回一个整数列表:
public List<Integer> GetIListImpl() {
return new ArrayList<Integer>();
}
但是,如果我想让调用者指定通用类型怎么办?像这样的东西,尽管在语法上我不确定如何去做:
public List<T> GetIListImpl<T>() {
return new ArrayList<T>();
}
用法是:
List<String> = GetIListImpl<String>();
static
参数化类型的通用工厂方法看来您想编写方便的工厂方法来实例化通用集合。
您可以编写如下通用方法:
public static <T> List<T> newArrayList() {
return new ArrayList<T>();
}
public static <K,V> Map<K,V> newHashMap() {
return new HashMap<K,V>();
}
然后,您可以简单地编写:
// absolutely type-safe!!! no compilation warnings at all!!!
List<String> names = newArrayList();
List<Integer> nums = newArrayList();
Map<String, List<String>> map = newHashMap();
请注意,在某些情况下,上述方法不必须static
的,你可以选择离开了实施class
的名字出来的方法和只使用interface
名称(例如newList
,newMap
)。
这种通用的类型推断static
工厂方法实际上已被 有效Java 2nd Edition所 认可 ;它具有作为书中讨论的 第一 项的独特特权。
以下是 第1项static
_的相关引号 :考虑使用_ 工厂方法而不是构造函数 :
一个 第四 的优点
static
工厂方法是它们减少了创建参数化类型实例的详细程度。不幸的是,当调用参数化类的构造函数时,即使它们从上下文中是显而易见的,也必须指定类型参数。这通常需要您连续两次提供类型参数:
Map<String,List<String>> m = new HashMap<String,List<String>>();
随着类型参数的长度和复杂性的增加,这种冗余规范很快变得很痛苦。
static
但是,对于工厂,编译器可以为您确定类型参数。这称为 类型推断 。例如,
假设 该HashMap
提供该static
工厂:public static <K,V> HashMap<K,V> newInstance() { return new HashMap<K,V>(); }
然后,您可以使用简洁的替代方法替换上面的冗长声明:
Map<String,List<String>> m = HashMap.newInstance();
不幸的是,诸如1.6之类的标准集合实现从版本1.6开始
HashMap
就没有static
工厂方法,但是您可以将这些方法放在自己的实用程序类中。更重要的是,您可以static
在自己的参数化类中提供此类工厂。
该项目还规定了这些static
工厂方法的通用命名约定:
getInstance
-返回由参数[…]描述的实例newInstance
-类似getInstance
,除了它保证返回的每个实例都与其他实例不同。new
Type
-像newInstance
,但是在工厂方法位于其他类中时使用。Type
指示工厂方法返回的对象的类型。
在大多数情况下,您不必显式提供类型参数,因为Java泛型类型推断系统通常可以确定您需要什么。
不过,为了提供显式类型参数,语法是将其放在方法名称 之前 (而不是 之后 )。这是使用显式参数<T> List<T> emptyList()
从中调用泛型方法的示例java.util.Collections
:
Collections.<String>emptyList();
// Collections.emptyList<String>(); // DOES NOT COMPILE
请注意,泛型方法调用的显式类型参数化的语法要求是,您 必须 限定类型(if
static
)或要在其上调用方法的对象,即使它们不是显式参数化也可以省略。
应该注意的是,Guava实际上已经为Java Collections
Framework中static
的类型提供了工厂方法:
从主要方面package com.google.common.collect
:
Lists.newArrayList()
,newLinkedList()
,…Sets.newHashSet()
,newTreeSet()
,newEnumSet(…)
,…Maps.newHashMap()
,newTreeMap()
,newEnumMap(…)
,…实际上,按照 Effective Java 2nd Edition
建议的精神,Guava自己的集合不提供public
构造函数,而是提供static create()
工厂方法:
HashMultiSet.create()
,一个Multiset
实现TreeMultimap.create()
,一个Multimap
实现该库的其余部分还提供了许多非常有用的功能。
问题内容: 我是java泛型的新手,我的问题是: 在上面的语句中,当函数的返回类型为void时,为什么我们以前使用过?为什么此语法有效? 根据理论,方法本身可以是返回类型吗? 我的参考程序是 问题答案: 在这里没有什么做的返回类型; 这意味着这是一个通用函数,可以采用各种类型的数组。为了更容易理解,代码可能是这样的: 所以它告诉函数 “有一个通用类型,您接受的数组,因此,例如,如果我用您接受的通用
问题内容: 我有一个代表文本片段的泛型类。该文本片段可能具有多种不同模式(突出显示的不同类型)中的任何一种。这些模式用枚举表示。每个项目的Enum可能不同,但是它必须实现一个接口,该接口提供了一种将其中两个结合的方法(可以突出显示并加粗显示)。所以我有一个界面: 然后我的TextFragment是文本字符串和模式的容器。但是当我尝试声明该类时: 我收到以下错误: 令牌“扩展”的语法错误,预期 根据
如何获取这个类的类型?对于上下文,我使用ModelMapper,我需要类类型T从S转换为T。 背景: 我已经尝试了N种方法,其中我放置了“//一些方法来获取类型”,但没有任何效果。例如: 或
主要内容:泛型集合,泛型类,泛型方法,泛型的高级用法前面我们提到 Java 集合有个缺点,就是把一个对象“丢进”集合里之后,集合就会“忘记”这个对象的数据类型,当再次取出该对象时,该对象的编译类型就变成了 Object 类型(其运行时类型没变)。 Java 集合之所以被设计成这样,是因为集合的设计者不知道我们会用集合来保存什么类型的对象,所以他们把集合设计成能保存任何类型的对象,只要求具有很好的通用性,但这样做带来如下两个问题: 集合对元素类型没有
本小节我们将学习 Java5 以后出现的一个特性:泛型(Generics)。通过本小节的学习,你将了解到什么是泛型,为什么需要泛型,如何使用泛型,如何自定义泛型,类型通配符等知识。 1. 什么是泛型 泛型不只是 Java 语言所特有的特性,泛型是程序设计语言的一种特性。允许程序员在强类型的程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须做出声明。 我们在上一小节已经了解到,Java
Pair泛型的实际参数类型是 Interger , 为什么不能赋值给 Number