Java: Generics 泛型

[b][align=center][size=medium]Generics allow you to abstract over types[/size][/align][/b]这里的 types 指的是什么?The Java programming language includes classes and interfaces, both are collectively re-ferred to as types. (见附件 Choosing Efficient Inheritance Patterns for Java Generics)

[b]好文一篇 - Java Generics FAQs:
[url]http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html[/url]
Java Tutorials - Generics(Updated):
[url]http://docs.oracle.com/javase/tutorial/java/generics/index.html[/url][/b]
Java Tutorials - Generics(老的,看看即可):
[url]http://docs.oracle.com/javase/tutorial/extra/generics/intro.html[/url]
[url]http://www.oracle.com/technetwork/articles/javase/generics-136597.html[/url]
Java 1.5 Generics Tutorial: How Generics in Java works with Example of Collections, Best practices, Gotchas:
[url]http://javarevisited.blogspot.com/2011/09/generics-java-example-tutorial.html[/url]


[align=center][size=medium][color=red][b]几个概念:[/b][/color][/size][/align]
[b]generic type[/b][quote]A generic type is a [b]generic class[/b] or interface that is parameterized over types.[/quote]
[b]type parameter[/b](also called type variable)[quote]A place holder for a type argument.
Generic types have one or more type parameters.
Each type parameter is replaced by a type argument when an instantiation of the generic type.

By convention, type parameter names are[b] single, uppercas[/b]e letters. This stands in sharp contrast to the variable naming conventions that you already know about, and with good reason: Without this convention, it would be difficult to tell the difference between a type variable and an ordinary class or interface name.
The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections Framework)
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types[/quote]
[b]type argument[/b][quote]A reference type or a wildcard that is used for instantiation of a generic type or a reference type used for instantiation of a generic method. An actual type argument replaces the formal(形式化的) type parameter used in the declaration of the generic type or method.[/quote]
[b]parameterized type[/b][quote]The instantiation(or invocation) of a generic type with actual type arguments is called a parameterized type[/quote]
[b]type inference[/b][quote]Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable. The inference algorithm determines the types of the arguments and, if available, the type that the result is being assigned, or returned. Finally, the inference algorithm tries to find the most specific type that works with all of the arguments.[/quote]

[align=center][size=medium][color=red][b]例子[/b][/color][/size][/align]

/**
* List & ArrayList 都是 generic type(细说的话,前者是 generic interface, 后者是 generic class)
* List & Array 类定义上的 <E> 中的 E 为 type parameter(also called type variable)
* Integer 为 type argument
* List<Integer> 为 parameterized type
*
*/
List<Integer> list = new ArrayList<Integer>();



[b][color=red][align=center][size=medium]Generic Methods[/size][/align][/color][/b]Not only types can be generic, but methods can be generic, too. Static and non-static methods as well as constructors can have type parameters. The syntax for declaration of the formal type parameters is similar to the syntax for generic types. The type parameter section is delimited by angle brackets and appears before the method's return type. Its syntax and meaning is identical to the type parameter list of a generic type.


[b][color=red][align=center][size=medium]Wildcards(通配符)[/size][/align][/color][/b][url]http://docs.oracle.com/javase/tutorial/java/generics/subtyping.html[/url]
In generic code, the question mark ([b]?[/b]), called the wildcard, represents an unknown type, or a family of types.
There are 3 different flavors of wildcards:
" ? " - the [b]unbounded wildcard[/b]. It stands for the family of all types.
" ? extends Type " - a wildcard with an [b]upper bound[/b]. It stands for the family of all types that are subtypes of Type , type Type being included.
" ? super Type " - a wildcard with a [b]lower bound[/b]. It stands for the family of all types that are supertypes of Type , type Type being included.
[color=red][b][size=small][align=center]PECS (short for Producer extends and Consumer super)[/align][/size][/b][/color][url]http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs[/url][quote]要站在collection的角度理解 producer & consumer:
当需要 get(从 collection 中取) 时,collection 扮演的是 producer 的角色,所以使用 extends;
当需要 put(往 collection 中放) 时,collection 扮演的是 consumer 的角色,所以使用super。[/quote]


[b]Bounded Type Parameter 和 upper bounded wildcard 的区别是什么?[/b]
[url]http://stackoverflow.com/questions/1750273/what-is-the-difference-between-bounded-wildcard-and-type-parameters?rq=1[/url]
[url]http://stackoverflow.com/questions/3486689/java-bounded-wildcards-or-bounded-type-parameter[/url]


[b]泛型与继承:[/b]
[b][url]http://www.ibm.com/developerworks/cn/java/j-lo-gj/[/url][/b][quote]在 Java 语言中,我们可以将某种类型的变量赋值给其父类型所对应的变量,例如,String 是 Object 的子类型,因此,我们可以将 String 类型的变量赋值给 Object 类型的变量,甚至可以将 String [ ] 类型的变量(数组)赋值给 Object [ ] 类型的变量,即 String [ ] 是 Object [ ] 的子类型。
上述情形恐怕已经深深地印在了广大读者的脑中,对于泛型来讲,上述情形有所变化,因此请广大读者务必引起注意。为了说明这种不同,我们还是先来分析一个小例子,代码如下所示:
List<String> ls = new ArrayList<String>(); 
List<Object> lo = ls;
lo.add(new Integer());
String s = ls.get(0);
上述代码的第二行将 List<String>赋值给了 List<Object>,按照以往的经验,这种赋值好像是正确的,因为 List<String>应该是 List<Object>的子类型。这里需要特别注意的是,这种赋值在泛型当中是不允许的! List<String>也不是 List<Object>的子类型。
如果上述赋值是合理的,那么上面代码的第三行的操作将是可行的,因为 lo是 List<Object>,所以向其添加 Integer 类型的元素应该是完全合法的。读到此处,我们已经看到了第二行的这种赋值所潜在的危险,它破坏了泛型所带来的类型安全性。
[b]一般情况下,如果 A 是 B 的子类型,C 是某个泛型的声明,那么 C<A>并不是 C<B>的子类型,我们也不能将 C<A>类型的变量赋值给 C<B>类型的变量[/b]。这一点和我们以前接触的父子类型关系有很大的出入,因此请读者务必引起注意。[/quote]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值