- 浏览: 158763 次
- 性别:
- 来自: 奥克兰
文章分类
最新评论
-
u012625419:
...
CXF之用spring配置服务端和客户端实例(转) -
bambooshangye:
CXF之用spring配置服务端和客户端实例(转) -
最佳蜗牛:
写的很好,谢谢!
tomcat下的server.xml文件和context.xml (转) -
mohaowen1989:
亲 有中文版的么?在grails基础上的spring-secu ...
Simplified Spring Security with Grails(转) -
douhongyang:
挺好,,思路很清晰,
spring security详解教程 (转)
Type Parameters
Fundamentals
What is a type parameter?
A place holder for a type argument. | |
Generic types have one or more type parameters.
Example of a parameterized type: interface Comparable<E> {The identifier E is a type parameter. Each type parameter is replaced by a type argument when an instantiation of the generic type, such as Comparable<Object> or Comparable<? extends Number> , is used. |
|
LINK TO THIS | TypeParameters.FAQ001 |
REFERENCES |
How
is a generic type defined?
What is a bounded type parameter? Where is a type parameter visible (or invisible)? |
What is a bounded type parameter?
A type parameter with one or more bounds. The bounds restrict the set of types that can be used as type arguments and give access to the methods defined by the bounds. | |
When you declare a type parameter
T
and use it
in the implementation of a generic type or method, the type parameter
T
still denotes an unknown type. The compiler knows that
T
is a place holder for a type, but it does not know anything about the
type.
This is okay in some implementations, but insufficient in others.
Example (of a generic type without bounds): public class Hashtable<Key,Data> {The implementation of class Hashtable invokes the methods hashCode and equals on the unknown Key type. Since hashCode and equals are methods defined in class Object and available for all reference types, not much need to be known about the unknown Key type. This changes substantially, when we look into the implementation of sorted sequence. Example (of a generic type, so far without bounds): public interface Comparable<T> {The implementation of class TreeMap invokes the method compareTo on the unknown Key type. Since compareTo is not defined for arbitrary types the compiler refuses to invoke the compareTo method on the unknown type Key because it does not know whether the key type has a compareTo method. In order to allow the invocation of the compareTo method we must tell the compiler that the unknown Key type has a compareTo method. We can do so by saying that the Key type implements the Comparable<Key> interface. We can say so by declaring the type parameter Key as a bounded parameter. Example (of the same generic type, this time with bounds): public interface Comparable<T> {In the example above, the type parameter Key has the bound Comparable<Key> . Specification of a bound has two effects:
|
|
LINK TO THIS | TypeParameters.FAQ002 |
REFERENCES |
When
would I use a wildcard parameterized with a lower bound?
What is a type parameter bound? Which types are permitted as type parameter bounds? Can I use different instantiations of a same generic type as bounds of a type parameteer? Does a bound that is a class type give access to all its public members? Can I use a type parameter as part of its own bounds or in the declaration of other type parameters? |
Type Parameter Bounds
What is a type parameter bound?
A reference type that is used to further describe a type parameter. It restricts the set of types that can be used as type arguments and gives access to the non-static methods that it defines. | |
A type parameter can be unbounded. In this case any
reference type can be used as type argument to replace the unbounded
type
parameter in an instantiation of a generic type.
Alternatively can have one or several bounds. In this case the type argument that replaces the bounded type parameter in an instantiation of a generic type must be a subtype of all bounds. The syntax for specification of type parameter bounds is: <TypeParameter extends Class & Interface 1 & ... & Interface N >A list of bounds consists of one class and/or several interfaces. Example (of type parameters with several bounds): class Pair<A extends Comparable<A> & Cloneable ,This is a generic class with two type arguments A and B , both of which have two bounds. |
|
LINK TO THIS | TypeParameters.FAQ101 |
REFERENCES |
What
is the difference between a wildcard bound and a type parameter bound?
Which types are permitted as type parameter bounds? Can I use different instantiations of a same generic type as bounds of a type parameteer? |
Which types are permitted as type parameter bounds?
All classes, interfaces and enum types including parameterized types, but no primitive types and no array types. | |
All classes, interfaces, and enum types can be used as
type parameter bound, including nested and inner types. Neither
primitive
types nor array types be used as type parameter bound.
Examples (of type parameter bounds): class X0 <T extends int > { ... } // errorThe code sample shows that primitive types such as int and array types such as Object[] are not permitted as type parameter bound. Class types, such as Number or String , and interface types, such as Runnable , are permitted as type parameter bound. Enum types, such as Thread.State are also permitted as type parameter bound. Thread.State is an example of a nested type used as type parameter bound. Non-static inner types are also permitted. Raw types are permitted as type parameter bound; List is an example. Parameterized types are permitted as type parameter bound, including concrete parameterized types such as List<String> , bounded wildcard parameterized types such as List<? extends Number> and Comparable<? super Long> , and unbounded wildcard parameterized types such as Map.Entry<?,?> . A bound that is a wildcard parameterized type allows as type argument all types that belong to the type family that the wildcard denotes. The wildcard parameterized type bound gives only restricted access to fields and methods; the restrictions depend on the kind of wildcard. Example (of wildcard parameterized type as type parameter bound): class X< T extends List<? extends Number> > {Reference variables of type T (the type parameter) are treated like reference variables of a wildcard type (the type parameter bound). In our example the consequence is that the compiler rejects invocation of methods that take an argument of the "unknown" type that the type parameter stands for, such as List.add , because the bound is a wildcard parameterized type with an upper bound. At the same time the bound List<? extends Number> determines the types that can be used as type arguments. The compiler accepts all type arguments that belong to the type family List<? extends Number> , that is, all subtypes of List with a type argument that is a subtype of Number . Note, that even types that do not have subtypes, such as final classes and enum types, can be used as upper bound. In this case there is only one type that can be used as type argument, namely the type parameter bound itself. Basically, the parameterization is pointless then. Example (of nonsensical parameterization): class Box< T extends String > {The compiler rejects all type arguments except String as "not being within bounds". The type parameter T is not needed and the Box class would better be defined as a non-parameterized class. |
|
LINK TO THIS | TypeParameters.FAQ102 |
REFERENCES |
What
is a type parameter bound?
Can I use a type parameter as a type parameter bound? Can I use different instantiations of a same generic type as bounds of a type parameter? Can I use a type parameter as part of its own bounds or in the declaration of other type parameters? How do unbounded wildcard instantiations of a generic type relate to other instantiations of the same generic type? How do wildcard instantiations with an upper bound relate to other instantiations of the same generic type? How do wildcard instantiations with a lower bound relate to other instantiations of the same generic type? Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type? |
Can I use a type parameter as a type parameter bound?
Yes. | |
A type parameter can be used as the bound of another type
parameter.
Example (of a type parameter used as a type parameter bound): class Triple <T> {In this example the type parameter T of the parameterized class is used as bound of the type parameters U , V and W of a parameterized instance method of that class. Further opportunities for using type parameters as bounds of other type parameters include situations where a nested type is defined inside a generic type or a local class is defined inside a generic method. It is even permitted to use a type parameter as bound of another type parameter in the same type parameter section. |
|
LINK TO THIS | TypeParameters.FAQ102A |
REFERENCES |
Can
I use a type parameter as part of its own bounds or in the declaration
of other type parameters?
Which types are permitted as type parameter bounds? Where is a type parameter visible (or invisible)? Can I use different instantiations of a same generic type as bounds of a type parameteer? What is the difference between a wildcard bound and a type parameter bound? |
Can
I use different instantiations of a same generic type as bounds of a
type
parameter?
No, at most one instantiation of the same generic type can appear in the list of bounds of a type parameter. | |
Example (of illegal use of two instantiations of the same
generic type as bounds of a type parameter):
class ObjectStore<T extends Comparable<T> & Comparable<String> > { // errorIn the example the type parameter T is required to be Comparable<T> , that is, comparable to its own type. This is needed for storing objects of type T in a TreeSet<T> . At the same time the type parameter T is required to be Comparable<String> , because we want to invoke the type parameter's compareTo(String) method. Remember, type parameter bounds are needed to give the compiler access to the type parameters non-static methods. In this (admittedly contrived) example, we need to specify two instantiations of the Comparable interface as bound of the type parameter, but the compiler rejects it. The reason for this restriction is that there is no type that is a subtype of two different instantiations of the Comparable interface and could serve as a type argument. It is prohibited that a type implements or extends two different instantiations of the same interface. This is because the bridge method generation process cannot handle this situation. Details are discussed in a separate FAQ entry (click here ). If no class can ever implement both instantiations of Comparable , there is no point to a bounds list that requires it. The class in our example would not be instantiable because no type can ever be within bounds, except perhaps class String . In practice, you will need to work around this restriction. Sadly, there might be situations in which there is no workaround at all. |
|
LINK TO THIS | TypeParameters.FAQ103 |
REFERENCES |
Can
a class implement different instantiations of the same generic
interface?
What is type erasure? What is a bridge method? How does type erasure work when a type parameter has several bounds? How can work around the restriction that a type parameter cannot have different instantiations of a same generic type as its bounds? |
How
can I work around the restriction that a type parameter cannot have
different
instantiations of a same generic type as its bounds?
Usually there is no satisfactory workaround. | |
Let us use the example from the previous question for our
search of a workaround.
Example (of illegal use of two instantiations of the same generic type as bounds of a type parameter): class ObjectStore<T extends Comparable<T> & Comparable<String> > { // errorIn the example the type parameter T is required to be Comparable<T> , because objects of type T are stored in a TreeSet<T> . At the same time the type parameter T is required to be Comparable<String> , because we invoke the type parameter's compareTo(String) method. The compiler rejects the attempt of specifying two instantiations of the Comparable interface as bound of the type parameter. One workaround for the example above could be the following: we could drop the requirement that the parameter T must be Comparable<T> , because the corresponding compareTo(T) method is not invoked in the implementation of the generic class itself, but in the operations of the Treeset<T> . By dropping the requirement we would risk that a type argument is supplied that is not Comparable<T> and will cause ClassCastException s when operations of the TreeSet<T> are invoked. Clearly not a desirable solution, but perhaps a viable one for this particular example. However, this might not be a solution if the class uses the type parameter in a slightly different way. For instance, if both compareTo methods were called in the implementation of the generic class, then we could not drop any of the bounds. Example (another class with illegal use of two instantiations of the same generic type as bounds of a type parameter): class SomeClass<T extends Comparable<T> & Comparable<String> > { // errorIf the methods of the bounds are invoked in the class implementation, then dropping one of the conflicting bounds does not solve the problem. One could consider use of an additional interface, such as a CombinedComparable interface that combines the two required interfaces into one interface. Example (conceivable work-around; does not work): interface CombinedComparable<T> {However, this is not really a viable solution, because it excludes class String as a type argument. String is a class that is comparable to itself and to String , but it is does not implement a CombinedComparable interface. Hence type String is not within bounds. Another conceivable alternative is definition of one new interface per instantiation needed, such as a parameterized SelfComparable and a non-parameterized StringComparable interface. Again, this excludes class String as a potential type argument. If it acceptable that class String is excluded as a potential type argument then the definition of additional interfaces might be a viable workaround. But there remain some situations, in which additional interfaces do not help. For instance, if the type parameter is used as type argument of another parameterized method, then it must itself be within the bounds of that other type parameter. Example (another class with illegal use of two instantiations of the same generic type as bounds of a type parameter): class AnUnrelatedClass {No solution sketched out above would address this situation appropriately. If we required that the type parameter be CombinedComparable , it would not be within the bounds of at least one of the two invoked methods. Note, that the CombinedComparable interface can be a subinterface of only one of the two instantiations of Comparable , but not both. Example (conceivable work-around; does not work): interface CombinedComparable<T> extends Comparable<String> {The same happens when we require that the type parameter be SelfComparable and StringComparable . Even if both were subinterfaces of the respective instantiation of Comparable , there cannot be a class that implements both, because that class would indirectly implement the two instantiations of Comparable . Ultimately the realization is that, depending on the circumstances, there might not be a work around at all. |
|
LINK TO THIS | TypeParameters.FAQ104 |
REFERENCES |
Can
I use different instantiations of a same generic type as bounds of a
type
parameter?
Can a class implement different instantiations of the same parameterized interface? |
Does a bound that is a class type give access to all its public members?
Yes, except any constructors. | |
A bound that is a class gives access to all its public
members, that is, public fields, methods, and nested type. Only
constructors
are not made accessible, because there is no guarantee that a subclass
of the bound has the same constructors as the bound.
Example (of a class used as bound of a type parameter): public class SuperClass {The bound SuperClass gives access to its nested types, static fields and methods and non-static fields and methods. Only the constructor is not accessible. This is because constructors are not inherited. Every subclass defines its own constructors and need not support its superclass's constructors. Hence there is no guarantee that a subclass of SuperClass will have the same constructor as its superclass. Although a superclass bound gives access to types, fields and methods of the type parameter, only the non-static methods are dynamically dispatched. In the unlikely case that a subclass redefines types, fields and static methods of its superclass, these redefinitions would not be accessible through the superclass bound. Example (of a subclass of the bound used for instantiation): public final class SubClass extends SuperClass { // static membersCalling the nonStaticMethod results in invocation of the subclass's overriding version of the nonStaticMethod . In contrast, the subclass's redefinitions of types, fields and static methods are not accessible through the bounded parameter. This is nothing unusual. First, it is poor programming style to redefine in a subclass any of the superclass's nested types, fields and static methods. Only non-static methods are overridden. Second, the kind of hiding that we observe in the example above also happens when a subclass object is used through a superclass reference variable. |
|
LINK TO THIS | TypeParameters.FAQ105 |
REFERENCES |
How do I decrypt "Enum<E extends Enum<E>>"?
As a type that can only be instantiation for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype arguments (or otherwise depend on the subtype). | |
The context in which
"
Enum<E extends
Enum<E>>
"
appears is the declaration of the
Enum
class in package
java.lang
:
public abstract class Enum<E extends Enum<E>> {The type Enum is the common base class of all enumeration types. In Java an enumeration type such as Color is translated into a class Color that extends Enum<Color> . The purpose of the superclass Enum is to provide functionality that is common to all enumeration types. Here is a sketch of class Enum : public abstract class Enum< E extends Enum<E>> implements Comparable< E >, Serializable {The surprising feature in the declaration " Enum<E extends Enum<E>> " is the fact that the newly defined class Enum and its newly defined type parameter E appear in the bound of that same type parameter. It means that the Enum type must be instantiated for one of its subtypes. In order to understand why this makes sense, consider that every enum type is translated into a subtype of Enum . Here is the contrived enum type Color : enum Color {RED, BLUE, GREEN}The compiler translates it into the following class: public final class Color extends Enum<Color> {The inheritance has the effect that the Color type inherits all the methods implemented in Enum<Color> . Among them is the compareTo method. The Color.compareTo method should probably take a Color as an argument. In order to make this happen class Enum is generic and the Enum.compareTo method takes Enum 's type parameter E as an argument. As a result, type Color derived from Enum<Color> inherits a compareTo method that takes a Color as and argument, exactly as it should. If we dissect the declaration " Enum<E extends Enum<E>> " we can see that this pattern has several aspects. First, there is the fact that the type parameter bound is the type itself: " Enum <E extends Enum <E>> ". It makes sure that only subtypes of type Enum are permitted as type arguments. (Theoretically, type Enum could be instantiated on itself, like in Enum<Enum> , but this is certainly not intended and it is hard to imagine a situation in which such an instantiation would be useful.) Second, there is the fact that the type parameter bound is the parameterized type Enum <E> , which uses the type parameter E as the type argument of the bound. This declaration makes sure that the inheritance relationship between a subtype and an instantiation of Enum is of the form " X extends Enum<X> ". A subtype such as " X extends Enum<Y> " cannot be declared because the type argument Y would not be within bounds; only subtypes of Enum<X> are within bounds. Third, there is the fact that Enum is generic in the first place. It means that some of the methods of class Enum take an argument or return a value of an unknown type (or otherwise depend on an unknown type). As we already know, this unknown type will later be a subtype X of Enum<X> . Hence, in the parameterized type Enum<X> , these methods involve the subtype X , and they are inherited into the subtype X . The compareTo method is an example of such a method; it is inherited from the superclass into each subclass and has a subclass specific signature in each case. To sum it up, the declaration " Enum<E extends Enum<E>> " can be decyphered as: Enum is a generic type that can only be instantiated for its subtypes, and those subtypes will inherit some useful methods, some of which take subtype specific arguments (or otherwise depend on the subtype). |
|
LINK TO THIS | TypeParameters.FAQ106 |
REFERENCES |
How
is a generic type defined?
What is a bounded type parameter? Where is a type parameter visible (or invisible)? |
http://www.angelikalanger.com/Images/bar-small
发表评论
发表评论
-
Java theory and practice: Are all stateful Web applications broken? (转)
2011-11-05 06:14 1195转自: http://www.ibm.com/deve ... -
Java SE 6 新特性: JMX 与系统管理(转)
2011-11-01 10:14 950转自: http://www.ibm.com/dev ... -
Top Ten Tomcat Configuration Tips(转)
2011-07-13 10:54 1593Coauthor's note: Now that writi ... -
Linux下两种自动启动Tomcat的方法(转)
2011-07-13 06:48 13046一. 简单的方法 ... -
Java 远程调用 debug (转)
2011-01-17 05:12 6002首先,JAVA自身支持调试功能,并提供了一个简单的调试工具-- ... -
tomcat下的server.xml文件和context.xml (转)
2010-12-06 09:01 2272<Server>元素 它代表 ... -
Portal(门户)是什么 (转)
2010-10-21 09:44 1015Portal 的组成可以分为三部份(1) Portal Ser ... -
JNDI到底是什么,有什么作用(转)
2010-09-05 16:52 1145JNDI的一篇文章 前端时间总是在搞不清JNDI ... -
JMX架构的了解 (转)
2010-08-27 09:58 942JMX应该说是关于网络应 ... -
SiteMesh 介绍 (转)
2010-08-26 05:14 1087How Does It Work? SiteMesh imp ... -
Linux常用命令和Linux服务器配置(转)
2010-08-25 13:31 1357Linux常用命令和Linux服务器配置 一、添加用户use ... -
JVM调优总结 -Xms -Xmx -Xmn -Xss(转)
2010-08-20 11:17 651堆大小设置 JVM 中最大堆大小有三方 ... -
JVM分代垃圾回收策略的基础概念(转)
2010-08-20 11:13 937文章总结了JVM垃圾回 ... -
HotSpot JVM 垃圾收集原理(转)
2010-08-20 10:44 867目的: 本 ... -
Java Runtime Monitoring 的一些名词解释
2010-08-20 10:38 1170Process Memory ... -
web.xml 中的listener、 filter、servlet 加载顺序及其详解(转)
2010-07-07 10:05 2675一、 1、启动一个WEB项目的时候,WEB容器会去读取它的 ...
相关推荐
根据提供的文件信息,我们可以深入探讨《Java泛型与集合》这本书中的关键知识点。该书由Maurice Naftalin和Philip Wadler合著,并于2007年由O'Reilly Media出版。以下是对该书内容的一个综合概述,旨在帮助读者理解...
在“Java Generics - Our Generics Class - Part 3 Source code”中,我们可以期待深入理解如何设计和实现自己的泛型类。这部分源代码可能包含对泛型类、泛型方法、通配符、边界以及类型擦除等概念的实例。以下是...
在本教程中,我们将深入探讨Java泛型的源码实现,特别是"Java-Generics-Our-Generics-Class-Part-3-Source-code"项目中的部分。 首先,泛型的主要目标是消除运行时类型转换异常,例如`ClassCastException`。通过在...
泛型与集合 使用 进行初步翻译. 将利用碎片时间进行整理和校对,完整的时间段适合做其他需要大量思考的事,如果你有兴趣欢迎提交PR。 TODO 数据校对 目录 2.4 获取和放置原则 2.5 数组 2.6 通配符与类型参数 ...
本项目"Java-Generics-and-Collections-Example"提供了对这两个主题的实例化理解和实践。 1. **Java泛型**: - 泛型是Java SE 5.0引入的新特性,它允许在类、接口和方法声明中使用类型参数,从而增强了类型检查和...
Java是一种广泛使用的面向对象的编程语言,以其平台独立性、安全性、健壮性和高性能而闻名。这个"java基础教程----精华版"显然是一份精心整理的资料,旨在帮助初学者快速掌握Java编程的基础知识。下面将详细介绍Java...
本书"Java Generics and Collections"深入探讨了这两个主题,帮助开发者编写更安全、更高效且可维护的代码。 首先,让我们来理解Java泛型。泛型是Java 5引入的一项特性,它允许在类、接口和方法中使用类型参数。这...
在有关Java核心的系列文章中,我们将继续学习2个新内容,即Generics和Collection,它们是Java中非常流行的对象。 泛型格式化参数化数据类型,以便我们可以将类,接口或方法用于许多不同的数据类型。 集合只是具有...
自JDK 1.5以来,Java编程语言引入了一系列重要的扩展功能,其中最重要的一个特性就是泛型(Generics)。本文档旨在向读者介绍Java中的泛型,并通过与类似语言如C++中的模板进行对比,帮助读者理解其相似性和差异性。...
【标题】"solder-generics-impl-0.5.1.zip" 是...了解这些知识点后,无论是想要使用"RestClient"进行REST服务的调用,还是研究"solder-generics-impl"的泛型实现,都有助于提升你的Java开发技能和对RESTful架构的理解。
Java泛型(Generics)是Java SE 5.0引入的一种新特性,它允许程序员在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,提高了代码的重用率。下面将根据给定的文件信息,深入解析Java泛型的一些核心知识点...
排序链表执行您的任务是实现排序的链表。 元素必须插入正确的位置。 不允许插入最后一个位置,然后再进行排序。 已经提供了基本骨架。 通用接口SortedList是实现的基础。 因此, SortedLinkedList必须实现它。...
总结起来,"Generics-four-arithmetic.zip_float_site:www.pudn.com"提供的示例展示了如何利用Java泛型创建一个灵活且类型安全的四则运算工具,它可以处理`int`、`double`和`float`类型的数值。通过这种方式,我们...