JavaGenericsFAQ 目录---Java泛型的知识,这一篇就够了

本文只是将JavaGenericsFAQ的目录列在了这里,具体请见:

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

1 About this FAQ

1) How is this FAQ organized at large? 
2) How are the individual answered questions organized? 
3) Whom is the FAQ for? 
4) How do I best read the FAQ - top-to-bottom or zig-zag? 

5) Whom do I contact when I have questions, comments or suggestions related to this FAQ?


2 Fundamentals of Java Generics
1) What are Java generics? 
Java Generics, sometimes used as a plural noun (generics) and sometimes as a singular noun (Generics), is a language feature of Java that allows for the definition and use of generic types and methods.


2) What is the primary purpose of Java generics? 
Java generics were invented primarily for implementation of generic collections.


3) What is the benefit of using Java generics? 
Early error detection at compile time.


4) What does type-safety mean?

In Java, a program is considered type-safe if it compiles without errors and warnings and does not raise any unexpected ClassCastException s at runtime.


3 Language Features of Java Generics

1) Which language features are related to Java generics?

Features for definition and use of generic types and methods.


Java Generics support definition and use of generic types and methods.  It provides language features for the following purposes: 
definition of a generic type
definition of a generic method
type parameters
type parameter bounds
type arguments
wildcards
wildcard bounds
wildcard capture
instantiation of a generic type
raw type
concrete instantiation
wildcard instantiation
instantiation of a generic method
automatic type inference
explicit type argument specification


3.1 Generic Types
3.1.1 Fundamentals 
1) What is a generic or parameterized type?
A generic type is a type with formal type parameters. A parameterized type is an instantiation of a generic type with actual type arguments.


2) How do I define a generic type?
Like a regular type, but with a type parameter declaration attached.


3) Are there any types that cannot have type parameters?
All types, except enum types, anonymous inner classes and exception classes, can be generic..


4) How is a generic type instantiated (to form a parameterized type)?
By providing a type argument per type parameter. 


5) Why do instantiations of a generic type share the same runtime type?
Because of type erasure.


6) Can I cast to a parameterized type?
Yes, you can, but under certain circumstances it is not type-safe and the compiler issues an "unchecked" warning.


7) Can I use parameterized types in exception handling?
No.  Exception and error types must not be generic.


8) Can generic types have static members?
Yes.


3.1.2 Concrete Instantiations 
1) What is a concrete instantiation of a generic type?
An instantiation of a generic type where all type arguments are concrete types rather than wildcards.


2) Is List<Object> a supertype of List<String>?
No, different instantiations of the same generic type for different concrete type arguments have no type relationship.


3) Can I use a concrete parmeterized type like any other type?
Almost.


4) Can I create an array whose component type is a concrete parameterized type?
No, because it is not type-safe.


5) Can I declare a reference variable of an array type whose component type is a concrete parameterized type?
Yes, you can, but you should not, because it is neither helpful nor type-safe.


6) How can I work around the restriction that there are no arrays whose component type is a concrete parameterized type?
You can use arrays of raw types, arrays of unbounded wildcard parameteriezd types, or collections of concrete parameteriezd types as a workaround.


7) Why is there no class literal for the concrete parameterized type?
Because parameterized type has no exact runtime type representation.


3.1.3 Raw Types 
1) What is the raw type?
The generic type without any type arguments.


2) Can I use a raw type like any other type?
To facilitate interfacing with non-generic (legacy) code.


3) Can I use a raw type like any other type?
Yes, but certain uses will result in "unchecked" warnings.


3.1.4 Wildcard Instantiations
1) What is a wildcard parameterized type?
An instantiation of a generic type where the type argument is a wildcard (as opposed to a concrete type).


2) What is an unbounded wildcard instantiation of a generic type?
An instantiation of a generic type where all type arguments are the unbounded wildcard " ? ".


3) What is the difference between the unbounded wildcard parameterized type and the raw type?
The compiler issues error messages for an unbounded wildcard parameterized type while it only reports "unchecked" warnings for a raw type.


4) Which methods and fields are accessible/inaccessible through a reference variable of a wildcard parameterized type?
It depends on the kind of wildcard.


5) Can I use a wildcard parameterized type like any other type?
No.  A wildcard parameterized type is not a type in the regular sense (different from a non-parameterized class/interface or a raw type).


6) Can I create an object whose type is a wildcard parameterized type?
No, not directly.


7) Can I create an array whose component type is a wildcard parameterized type?
No, because it is not type-safe.


8) Can I declare a reference variable of an array type whose component type is a bounded wildcard parameterized type?
Yes, you can, but you should not, because it is neither helpful nor type-safe.


9) Why is it allowed to create an array whose component type is an unbounded wildcard parameterized type ?
Because it is type-safe.


10) Can I declare a reference variable of an array type whose component type is an unbounded wildcard parameterized type?
Yes.


11) Can I derive from a wildcard instantiation of a parameterized type?
No, a  wildcard parameterized type is not a supertype.


12) Why is there no class literal for wildcard parameterized types ?
Because a wildcard parameterized type has no exact runtime type representation.


3.2 Generic Methods
3.2.1 Fundamentals
1) What is a generic method?
A method with type parameters.


2) How do I invoke a generic method?
Usually by calling it. Type arguments for generic methods need not be provided explicitly;  they are almost always automatically inferred.


3.3 Type Parameters
3.3.1 Fundamentals
1) What is a type parameter?
A place holder for a type argument.


2) 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.


3.3.2 Type Parameter Bounds
1) What is a bounded type parameter?
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.


2) 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.


3) Can I use a type parameter as a type parameter bound?
Yes.


4) 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.


5) 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.


6) Does a bound that is a class type give access to all its public members?
Yes, except any constructors.


7) 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).


8) Why is there no lower bound for type parameters?
Because it does not make sense for type parameters of classes; it would occasionally be useful in conjunction with method declarations, though.


3.3.3 Usage
1) Can I use a type parameter like a type?
No, a type parameter is not a type in the regular sense (different from a regular type such as a non-generic class or interface).


2) Can I create an object whose type is a type parameter?
No, because the compiler does not know how to create objects of an unknown type.


3) Can I create an array whose component type is a type parameter?
No, because the compiler does not know how to create an object of an unknown component type.


4) Can I cast to the type that the type parameter stands for?
Yes, you can, but it is not type-safe and the compiler issues an "unchecked" warning.


5) Can I use a type parameter in exception handling?
It depends.


6) Can I derive from a type parameter?
No, because a type parameter does not have a runtime type representation of it own.


7) Why is there no class literal for a type parameter?
Because a type parameter does not have a runtime type representation of its own.


3.3.4 Scope
1) Where is a type parameter visible (or invisible)?
Everywhere in the definition of a generic type or method, except any static context of a type.


2) Can I use a type parameter as part of its own bounds?
Yes, the scope of a type parameter includes the type parameter section itself.
3) Can I use the type parameter of an outer type as part of the bounds of the type parameter of an inner type or a method?
Yes, the type parameter of an enclosing generic type or method can be used in the type parameter section of an inner generic type or method.


3.3.5 Static Context
1) Is there one instances of a static field per instantiation of a generic type?
No, there is only one instance of a static field for all instantiations of a generic type.


2) Why can't I use a type parameter in any static context of the generic class?
Because the static context is independent of the type parameters and exists only once per raw type, that is, only once for all instantiations of a generic type.


3.4 Type Arguments
3.4.1 Fundamentals
1) What is a type argument?
A reference type that is used for the instantiation of a generic type or for the instantiation of a generic method, or a wildcard that is used for the instantiation of a generic type .  An actual type argument replaces the formal type parameter used in the declaration of the generic type or method.


2) Which types are permitted as type arguments?
All references types including parameterized types, but no primitive types.


3) Are primitive types permitted as type arguments?
No. Only reference types can be used as type arguments.


4) Are wildcards permitted as type arguments?
For instantiation of a generic type, yes. For instantiation of a generic method, no.


5) Are type parameters permitted as type arguments?
Yes.


6) Do type parameter bounds restrict the set of types that can be used as type arguments?
Yes, type arguments must be within bounds. 


7) Do I have to specify a type argument when I want to use a generic type?
No; you can use the so-called raw type, which is the generic type without type arguments.


8) Do I have to specify a type argument when I want to invoke a generic method?
No; a generic method can be used without type arguments.


3.4.2 Wildcards
1) What is a wildcard?
A syntactic construct that denotes a family of types.


2) What is an unbounded wildcard?
A wildcard without a bound.


3) What is a bounded wildcard?
A wildcard with either an upper or a lower bound.


4) What do multi-level wildcards mean?
It depends. 


5) If a wildcard appears repeatedly in a type argument section, does it stand for the same type?
No, each occurrence can stand for a different type.


3.4.3 Wildcard Bounds
1) What is a wildcard bound?
A reference type that is used to further describe the family of types denoted by a wildcard.


2) Which types are permitted as wildcard bounds?
All references types including parameterized types, but no primitive types.


3) What is the difference between a wildcard bound and a type parameter bound?
A wildcard can have only one bound, while a type parameter can have several bounds.  
A wildcard can have a lower or an upper bound, while there is no such thing as a lower bound for a type parameter. 




4 Practicalities - Programming With Java Generics
4.1 Using Generic Types
1) Should I prefer parameterized types over raw types?
Yes, using parameterized types has various advantages and is recommended, unless you have  a compelling reason to prefer the raw type.


Providing the type arguments rather than using the raw type has a couple of advantages: 
Improved readability
Better tool support 
Fewer ClassCastExceptions
Fewer casts
No unchecked warnings
No future deprecation


Raw types have an advantage, too: 
Zero learning effort


2) Why shouldn't I mix parameterized and raw types, if I feel like it? 
Because it is poor style and highly confusing to readers of your source code.


3) Should I use the generic collections or better stick to the old non-generic collections?
Provide type arguments when you use collections; it improves clarity and expressiveness of your source code.


4) What is a checked collection?
A view to a regular collection that performs a runtime type check each time an element is inserted.


5) What is the difference between a Collection<?> and a Collection<Object>?
Collection<Object> is a heterogenous collection, while Collection<?> is a homogenous collection of elements of the same unknown type.


6) How do I express that a collection is a mix of objects of different types?
Using wildcard instantiations of the generic collections.


7) What is the difference between a Collection<Pair<String,Object>>, a Collection<Pair<String,?>> and a Collection<? extends Pair<String,?>>?
All three types refer to collections that hold pairs where the first part is a String and the second part is of an arbitrary type.  The differences are subtle.


8) How can I make sure that the same wildcard stands for the same type?
In general you can't.


4.2 Using Generic Methods
1) Why doesn't method overloading work as I expect it?
Because there is only one byte code representation of each generic type or method.


2) Why doesn't method overriding work as I expect it?
Because the decision regarding overriding vs. overloading is based on the generic type, not on any instantiation thereof.


4.3 Coping With Legacy
1) What happens when I mix generic and non-generic code?
The compiler issues lots of "unchecked" warnings.


2) Should I re-engineer all my existing classes and generify them?
The compiler issues lots of "unchecked" warnings.


3) How do I generify an existing non-generic type or method?
There are no carved-in-stone rules.  It all depends on the intended semantics of the generified type or method.


4) Can I safely generify a supertype, or does it affect all subtypes?
Yes, we can generify non-generic legacy supertypes without affecting the non-generic legacy subtypes - provided the subtype method's signature is identical to the erasure of the supertype method's signature.


5) How do I avoid breaking binary compatibility when I generify an existing type or method?
Sometimes a dummy bound does the trick.


4.4 Defining Generic Types and Methods
1) Which types should I design as generic types instead of defining them as regular non-generic types?
Types that use supertype references in several places and where there is a correspondence between the occurrences of these supertypre references. 


2) Do generics help designing parallel class hierarchies?
Yes.


3) When would I use an unbounded wildcard instantiation instead of a bounded or concrete parameterized type  concrete parameterized type?
When you need a reifiable type.


4) When would I use a wildcard instantiation instead of a concrete parameterized type?
Whenever you need the supertype of all or some instantiations of a generic type.


5) When would I use a wildcard instantiation with an lower bound?
When a concrete parmeterized type would be too restrictive.


6) How do I recover the actual type of the this object in a class hierarchy?
With a getThis() helper method that returns the this object via a reference of the exact type.


7) What is the "getThis" trick?
A way to recover the type of the this object in a class hierarchy.


8) How do I recover the element type of a container?
By having the container carry the element type as a type token.


9) What is the "getTypeArgument" trick?
A technique for recovering the type argument from a wildcard parameterized type at run-time.


4.5 Designing Generic Methods
1) Why does the compiler sometimes issue an unchecked warning when I invoke a "varargs" method?
Because you pass in a variable argument list of reifiable types.


2) What is a "varargs" warning?
A warning that the compiler issues for the definition of certain methods with a variable argument list.


3) How can I suppress a "varargs" warning?
By using a @SafeVarargs annotation.


4) When should I refrain from suppressing a "varargs" warning?
When the varargs method in question can lead to heap pollution.


5) Which role do wildcards play in method signatures?
They broaden the set of argument or return types that a method accepts or returns.


6) Which one is better: a generic method with type parameters or a non-generic method with wildcards?
It depends.  There is not one-size-fits-all rule.


7) Under which circumstances are the generic version and the wildcard version of a method equivalent?
If there is a transformation between the generic and the wildcard version that maintains the semantics.


8) Under which circumstances do the generic version and the wildcard version of a method mean different things?
When a type parameter appears repeatedly in a generic method signature and in case of multi-level wildcards.


9) Under which circumstances is there no transformation to the wildcard version of a method possible?
 If a type parameter has more than one bound.


10) Should I use wildcards in the return type of a method?
Avoid it, if you can.


11) How do I implement a method that takes a wildcard argument?
Using a generic helper method and wildcard capture.


12) How do I implement a method that takes a multi-level wildcard argument?
Using a generic helper method and wildcard capture.


13) I want to pass a U and a X<U> to a method.  How do I correctly declare that method?
Using an upper bound wildcard parameterized type instead of a concrete parameterized type as the argument type.


4.6 Working With Generic Interfaces 
1) Can a class implement different instantiations of the same generic interface?
No, a type must not directly or indirectly derive from two different instantiations of the same generic interface.


2) Can a subclass implement another parameterized interface than any of its superclasses does?
No, the superclass determines which instantiation of a generic interface the entire class hierarchy must implement.


3) What happens if a class implements two generic interfaces that define the same method?
If the two method have the same erasure then the class is illegal and rejected with a compile-time error message.


4) Can an interface type nested into a generic type use the enclosing type's type parameters?
No, but as workaround you can generify the nested interface itself. 


4.7 Implementing Infrastructure Methods 
1) How do I best implement the equals method of a generic type?
Override Object.equals(Object) as usual and perform the type check using the unbounded wildcard instantiation.


2) How do I best implement the clone method of a generic type?
Override Object.clone() as usual and ignore the inevitable unchecked warnings.


4.8 Using Runtime Type Information 
1) What does the type parameter of class java.lang.Class mean?
The type parameter is the type that the Class object represents, e.g. Class<String> represents String .


2) How do I pass type information to a method so that it can be used at runtime?
By means of a Class object.


3) How do I generically create objects and arrays?
Using reflection.


4) How do I perform a runtime type check whose target type is a type parameter?
Using reflection.


4.9 Reflection
1) Which information related to generics can I access reflectively?
The exact static type information, but only inexact dynamic type information.


2) How do I retrieve an object's actual (dynamic) type?
By calling its getClass() method.


3) How do I retrieve an object's declared (static) type?
By finding the declaration's reflective representation and calling the appropriate getGeneric...() method.


4) What is the difference between a generic type and a parameterized type in reflection?
A generic type is represented by a Class object; a parameterized type is represented by a ParameterizedType object.


5) How do I figure out whether a type is a generic type?
By asking it whether it has type parameters.


6) Which information is available about a generic type?
All the information that is available for regular types plus information about the generic type's type parameters.


7) How do I figure out whether a type is a parameterized type?
By asking whether the type representation is a ParameterizedType .


8) Which information is available about a parameterized type?
Information about the parameterized type's type arguments, its corresponding raw type, and its enclosing type if it is a nested type or inner class.


9) How do I retrieve the representation of a generic method?
By retrieving the type erasure of the generic method.


10) How do I figure out whether a method is a generic method?
By asking it whether it has type parameters.


11) Which information is available about a generic method?
All the information that is available for regular methods plus information about the generic method's type parameters.


12) Which information is available about a type parameter?
The type parameter's name, its bounds, and the generic type or method that the type parameter belongs to.


13) What is a generic declaration?
Either a generic type or a generic method or a generic constructor.


14) What is a wildcard type?
A wildcard expression; it appears as the type argument of a parameterized type.


15) Which information is available about a wildcard?
The upper and the lower bound.




5 Technicalities - Under the Hood of the Compiler
5.1 Compiler Messages 
1) What is an "unchecked" warning?
A warning by which the compiler indicates that it cannot ensure type safety.




2) How can I disable or enable "unchecked" warnings? 
Via the compiler options -Xlint:unchecked and -Xlint:-unchecked and via the standard annotation @SuppressWarnings("unchecked") .


3) What is the -Xlint:unchecked compiler option?
The compiler option -Xlint:unchecked enables "unchecked" warnings, the option -Xlint:-unchecked disables all unchecked warnings.


4) What is the SuppressWarnings annotation?
The compiler option -Xlint:unchecked enables "unchecked" warnings, the option -Xlint:-unchecked disables all unchecked warnings.


5) How can I avoid "unchecked cast" warnings?
The compiler option -Xlint:unchecked enables "unchecked" warnings, the option -Xlint:-unchecked disables all unchecked warnings.


6) Is it possible to eliminate all "unchecked" warnings?
Almost.


7) Why do I get an "unchecked" warning although there is no type information missing?
Because the compiler performs all type checks based on the type erasure when you use a raw type.


5.2 Heap Pollution 
1) What is heap pollution?
Because the compiler performs all type checks based on the type erasure when you use a raw type.


2) When does heap pollution occur?
As a result of mixing raw and parameterized type, unwise casting, and separate compilation.


5.3 Type Erasure 
1) How does the compiler translate Java generics?
By creating one unique byte code representation of each generic type (or method) and mapping all instantiations of the generic type (or method) to this unique representation.


2) What is type erasure?
A process that maps a parameterized type (or method) to its unique byte code representation by eliding type parameters and arguments.


3) What is reification?
Representing type parameters and arguments of generic types and methods at runtime.  Reification is the opposite of type erasure .


4) What is a bridge method?
A synthetic method that the compiler generates in the course of type erasure.  It is sometimes needed when a type extends or implements a parameterized class or interface.


5) Under which circumstances is a bridge method generated?
When a type extends or implements a parameterized class or interface and type erasure changes the signature of any inherited method.


6) Why does the compiler add casts when it translates generics?
Because the return type of methods of a parameterized type might change as a side effect of type erasure.


7) How does type erasure work when a type parameter has several bounds?
The compiler adds casts as needed.


8) What is a reifiable type?
A type whose type information is fully available at runtime, that is, a type that does not lose information in the course of type erasure.


9) What is the type erasure of a parameterized type?
The type without any type arguments.


10) What is the type erasure of a type parameter?
The type erasure of its leftmost bound, or type Object if no bound was specified.


11) What is the type erasure of a generic method?
A method with the same name and the types of all method parameters replaced by their respective type erasures.


12) Is generic code faster or slower than non-generic code?
There is no perceivable difference.


13) How do I compile generics for use with JDK <= 1.4?
Use a tool like Retroweaver.


5.4 Type System 
1) How do parameterized types fit into the Java type system?
Instantiations of generic types have certain super-subtype relationship among each other and have a type relationship to their respective raw type.  These type relationships are relevant for method invocation, assignment and casts.


2) How does the raw type relate to instantiations of the corresponding generic type?
The raw type is the supertype of all instantiations of the corresponding generic type.


3) How do instantiations of a generic type relate to instantiations of other generic types that have the same type argument?
An instantiation of a generic type is the supertype of all instantiations of generic subtypes that have the same type argument.


4) How do unbounded wildcard instantiations of a generic type relate to other instantiations of the same type?
An instantiation of a generic type is the supertype of all instantiations of generic subtypes that have the same type argument.


5) How do wildcard instantiations with an upper bound relate to other instantiations of the same type?
A wildcard instantiation wild an upper bound is supertype of all instantiations of the same generic type where the type argument is a subtype of the upper bound.


6) How do wildcard instantiations with a lower bound relate to other instantiations of the same type?
A wildcard instantiation wild a lower bound is supertype of all instantiations of the generic type where the type argument is a supertype of the lower bound.


7) Which super-subtype relationships exist among instantiations of generic types?
This is fairly complicated and the type relationships are best determined setting up tables as explained in this FAQ entry. 


8) Which super-subset relationships exist among wildcards?
A super-subtype relationship between upper bounds leads to a super-subset relationship between the resulting upper bound wildcards, and vice versa for a lower bounds.


9) Does "extends" always mean "inheritance"?
No. 


5.5 Exception Handling 
1) Can I use parameterized types in exception handling?
No.  Exception and error types must not be generic.


2) Why are generic exception and error types illegal?
Because the virtual machine cannot distinguish between different instantiations of a generic exception type.


3) Can I use a type parameter in exception handling?
It depends. 


4) Can I use a type parameter in a catch clause?
No.


5) Can I use a type parameter in in a throws clause?
Yes.


6) Can I throw an object whose type is a type parameter?
In principle, yes, but in practice, not really.


5.6 Static Context 
1) How do I refer to static members of a parameterized type?
Using the raw type as the scope qualifier, instead of the any instantiation of the generic type.


2) How do I refer to a (non-static) inner class of a parameterized type?
Using an instantiation of the enclosing generic type as the scope qualifier, instead of the raw type.


3) How do I refer to an interface type nested into a parameterized type?
Using the raw type as the scope qualifier, instead of the any instantiation of the generic type.


4) How do I refer to an enum type nested into a parameterized type?
Using the raw type as the scope qualifier, instead of the any instantiation of the generic type.


5) Can I import a particular instantiation of generic type?
No.


6) Why are generic enum types illegal?
Because they do not make sense in Java.


5.7 Type Argument Inference 
1) What is type argument inference?
The automatic deduction of the type arguments at compile time.


2) Is there a correspondence between type inference for method invocation and type inference for instance creation?
Yes, the instance creation expression for a generic type is treated like invocation of a generic creator method.


3) What is the "diamond" operator?
It denotes the empty angle brackets that are used for type inference in new -expressions.


4) What is type argument inference for instance creation expressions?
The automatic deduction of the type arguments in a new -expression.


5) Why does the type inference for an instance creation expression fail?
Usually because there is not enough context information.


6) What is type argument inference for generic methods?
The automatic deduction of the type arguments of a generic method at compile time.


7) What explicit type argument specification?
Providing a type argument list when the method is invoked.


8) Can I use a wildcard as the explicit type argument of a generic method?
No, wildcards are not permitted as explicit type arguments of a generic method.


9) What happens if a type parameter does not appear in the method parameter list?
The compiler tries to infer the type argument from the calling context.


10) Why doesn't type argument inference fail when I provide inconsistent method arguments?
Because the "inconsistent" arguments might make sense to the compiler.


11) Why do temporary variables matter in case of invocation of generic methods?
Because of the automatic type argument inference.


5.8 Wildcard Capture 
1) What is the capture of a wildcard?
An anonymous type variable that represents the particular unknown type that the wildcard stands for.  The compiler uses the capture internally for evaluation of expressions and the term "capture of ?" occasionally shows up in error message.


2) What is the capture of an unbounded wildcard compatible to?
Nothing, except the unbounded wildcard itself. 


3) Is the capture of a bounded wildcard compatible to the bound?
No, not even if the bound is a final class. 


5.9 Wildcard Instantiations 
1) Which methods and fields are accessible/inaccessible through a reference variable of a wildcard type?
It depends on the kind of wildcard.


2) Which methods that use the type parameter in the argument or return type are accessible in an unbounded wildcard instantiation?
We cannot call methods through an unbounded wildcard parameterized type that take arguments of the "unknown" type.  But we can call methods that return objects of the "unknown" type.


3) Which methods that use the type parameter in the argument or return type are accessible in an upper bound wildcard instantiation?
We cannot call methods through an unbounded wildcard parameterized type that take arguments of the "unknown" type.  But we can call methods that return objects of the "unknown" type.


4) Which methods that use the type parameter in the argument or return type are accessible in a lower bound wildcard instantiation?
We can call methods through an unbounded wildcard parameterized type that take arguments of the "unknown" type.  But we cannot call methods that return objects of the "unknown" type.


5) Which methods that use the type parameter as type argument of a parameterized argument or return type are accessible in a wildcard instantiation?
We cannot call methods that use the type parameter as type argument in an argument type. We can call methods that use the type parameter as type argument in the return type; the returned value is accessible through a wildcard instantiation of the return type. 


6) Which methods that use the type parameter as upper wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?
We cannot call methods that use the type parameter as an upper wildcard bound  in an argument type, with an exception for access through a lower bound wildcard parameterized type. We can call methods that use the type parameter as the upper wildcard bound in the return type; the returned value is accessible through the unbounded wildcard instantiation of the return type. 


7) Which methods that use the type parameter as lower wildcard bound in a parameterized argument or return type are accessible in a wildcard instantiation?
We can call methods that use the type parameter as a lower wildcard bound in the return type; the returned value is accessible through a wildcard instantiation of the return type (which one depends on the wildcard parameterized type being used). We can call methods that use the type parameter as a lower wildcard bound  in an argument type; the argument type is restricted depending on the wildcard being use.


8) In a wildcard instantiation, can I read and write fields whose type is the type parameter?
It depends on the kind of wildcard.


9) Is it really impossible to create an object whose type is a wildcard parameterized type?
It is actually illegal and the compiler tries to prevent it, but there's a workaround.


5.10 Cast and instanceof
1) Which types can or must not appear as target type in an instanceof expression?
Only reifiable types are permitted.




5.11 Overloading and Overriding
1) What is method overriding?
When a subtype redefines a method that was inherited from a supertype.


2) What is method overloading?
When a class has two methods with the same name, but signatures that are not override-equivalent.


3) What is the  @Override annotation?
An annotation that you can attach to a method so that the compiler issues an error if the annotated method does not override any supertype method.


4) What is a method signature?
An identification of a method that consist of the method's name and its arguments types.


5) What is a subsignature?
A method signature that is identical to another method signature, or identical to the erasure of another method signature.


6) What are override-equivalent signatures?
Two method signatures where one signature is a subsignature of the other.


7) When does a method override its supertype's method?
When the subtype's method has a signature that is a subsignature of the supertype's method and the two methods have compatible return types and throws clauses.


8) What are covariant-return types?
Return types of overriding methods where the supertype method's return type is a supertype of the subtype method's return type.


9) What are substitutable return types?
The return type of an overriding subclass method must be substitutable for the superclass method's return type.


10) Can a method of a non-generic subtype override a method of a generic supertype?
Yes.


11) Can a method of a generic subtype override a method of a generic supertype?
Yes, but make sure you do not inadvertently overload instead of override.


12) Can a generic method override a generic one?
Yes.


13) Can a non-generic method override a generic one?
Yes.


14) Can a generic method override a non-generic one?
No.


15) What is overload resolution?
The process of determining the best match from a set of overloaded methods.


6 More Information on Java Generics
1) Where can I find a generics tutorial? 




2) Where can I find a specification of the Java generics language features? 




3) Which books cover Java generics? 




4) What webpages are devoted to Java generics?



Java泛型Java 5引入的新特性,可以提高代码的可读性和安全性,降低代码的耦合度。泛型是将类型参数化,实现代码的通用性。 一、泛型的基本语法 在声明类、接口、方法时可以使用泛型泛型的声明方式为在类名、接口名、方法名后面加上尖括号<>,括号中可以声明一个或多个类型参数,多个类型参数之间用逗号隔开。例如: ```java public class GenericClass<T> { private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } } public interface GenericInterface<T> { T getData(); void setData(T data); } public <T> void genericMethod(T data) { System.out.println(data); } ``` 其中,`GenericClass`是一个泛型类,`GenericInterface`是一个泛型接口,`genericMethod`是一个泛型方法。在这些声明中,`<T>`就是类型参数,可以用任何字母代替。 二、泛型的使用 1. 泛型类的使用 在使用泛型类时,需要在类名后面加上尖括号<>,并在括号中指定具体的类型参数。例如: ```java GenericClass<String> gc = new GenericClass<>(); gc.setData("Hello World"); String data = gc.getData(); ``` 在这个例子中,`GenericClass`被声明为一个泛型类,`<String>`指定了具体的类型参数,即`data`字段的类型为`String`,`gc`对象被创建时没有指定类型参数,因为编译器可以根据上下文自动推断出类型参数为`String`。 2. 泛型接口的使用 在使用泛型接口时,也需要在接口名后面加上尖括号<>,并在括号中指定具体的类型参数。例如: ```java GenericInterface<String> gi = new GenericInterface<String>() { private String data; @Override public String getData() { return data; } @Override public void setData(String data) { this.data = data; } }; gi.setData("Hello World"); String data = gi.getData(); ``` 在这个例子中,`GenericInterface`被声明为一个泛型接口,`<String>`指定了具体的类型参数,匿名内部类实现了该接口,并使用`String`作为类型参数。 3. 泛型方法的使用 在使用泛型方法时,需要在方法名前面加上尖括号<>,并在括号中指定具体的类型参数。例如: ```java genericMethod("Hello World"); ``` 在这个例子中,`genericMethod`被声明为一个泛型方法,`<T>`指定了类型参数,`T data`表示一个类型为`T`的参数,调用时可以传入任何类型的参数。 三、泛型的通配符 有时候,我们不知道泛型的具体类型,可以使用通配符`?`。通配符可以作为类型参数出现在方法的参数类型或返回类型中,但不能用于声明泛型类或泛型接口。例如: ```java public void printList(List<?> list) { for (Object obj : list) { System.out.print(obj + " "); } } ``` 在这个例子中,`printList`方法的参数类型为`List<?>`,表示可以接受任何类型的`List`,无论是`List<String>`还是`List<Integer>`都可以。在方法内部,使用`Object`类型来遍历`List`中的元素。 四、泛型的继承 泛型类和泛型接口可以继承或实现其他泛型类或泛型接口,可以使用子类或实现类的类型参数来替换父类或接口的类型参数。例如: ```java public class SubGenericClass<T> extends GenericClass<T> {} public class SubGenericInterface<T> implements GenericInterface<T> { private T data; @Override public T getData() { return data; } @Override public void setData(T data) { this.data = data; } } ``` 在这个例子中,`SubGenericClass`继承了`GenericClass`,并使用了相同的类型参数`T`,`SubGenericInterface`实现了`GenericInterface`,也使用了相同的类型参数`T`。 五、泛型的限定 有时候,我们需要对泛型的类型参数进行限定,使其只能是某个类或接口的子类或实现类。可以使用`extends`关键字来限定类型参数的上限,或使用`super`关键字来限定类型参数的下限。例如: ```java public class GenericClass<T extends Number> { private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } } public interface GenericInterface<T extends Comparable<T>> { T getData(); void setData(T data); } ``` 在这个例子中,`GenericClass`的类型参数`T`被限定为`Number`的子类,`GenericInterface`的类型参数`T`被限定为实现了`Comparable`接口的类。 六、泛型的擦除 在Java中,泛型信息只存在于代码编译阶段,在编译后的字节码中会被擦除。在运行时,无法获取泛型的具体类型。例如: ```java public void genericMethod(List<String> list) { System.out.println(list.getClass()); } ``` 在这个例子中,`list`的类型为`List<String>`,但是在运行时,`getClass`返回的类型为`java.util.ArrayList`,因为泛型信息已经被擦除了。 七、泛型的类型推断 在Java 7中,引入了钻石操作符<>,可以使用它来省略类型参数的声明。例如: ```java List<String> list = new ArrayList<>(); ``` 在这个例子中,`ArrayList`的类型参数可以被编译器自动推断为`String`。 八、总结 Java泛型是一个强大的特性,可以提高代码的可读性和安全性,降低代码的耦合度。在使用泛型时,需要注意它的基本语法、使用方法、通配符、继承、限定、擦除和类型推断等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值