G eneric P roGramminG
6.13 RESTRICTIONS ON GENERICS
6.13.7 Cannot use class
We cannot use .class for parameterized types. So the following are wrong: Class c = List<String>.class; //illegal
c = List<Integer>.class; //illegal c = List<Double>.class; //illegal
This is because unlike C++ templates, in Java generics, a separate class is not generated for each type argument. So, we must use raw type instead of parameterized type:
Class c = List.class;
KEYWORDS
Bounded type parameter—A type parameter that
accepts a restricted set of arguments
Generics—A construct to write parameterized classes,
interfaces and methods
Lower-bounded wildcard—The wildcard that
represents a set of unknown types restricted by a lower bound
Type argument—An argument passed to generic type
or method/constructor call
Type erasure—A technique by which Java compiler
translates generic classes/interfaces/methods to their no-generic counterparts
Type inference—Ability to find some type information
automatically from the arguments passed to methods or constructors.
Type parameter—A parameter accepted by generic
class, interface or method
Upper-bounded wildcard—The wildcard that
represents a set of unknown types restricted by an upper bound
Wildcard—The ‘?’ character used to represent an
unknown type in generics
Unbounded wildcard—The wildcard that represents
any unknown type
SUMMARY
Java generics allows us to write parameterized classes, interfaces and methods where parameters are type names. Although, the primary usage of generics is to abstract over types when working with collections, it is possible to write custom generic classes, interfaces and methods. Instead of relying on the programmer to keep track of object types and performing casts, which could lead to failures at runtime difficult to debug and solve, the compiler can help the programmer enforce a greater number of type checks and detect more failures at compile time.
It is possible to make both classes and interfaces generic. A class or an interface is generic if it accepts one or more type parameters. In general, any number of type parameters may be specified. They are specified in angular brackets separated by comma (,) and follow the class (or the interface) name
Like classes and interfaces, methods (including constructors) may use type parameters and are called generic methods. Sometimes it is possible to find some type information automatically from the arguments
passed to methods or constructors. This ability is known as type inference.
It is also possible to restrict the argument that a generic type/method will use using bounded type parameter. It is written as the type parameter followed by the extends keyword followed by the bound. A type parameter may have more than one bound. If one of the bounds is a class, it must be specified first.
The sub-typing differs in generics from traditional sub- typing. In general, given two concrete types A and B, AClass<A> has no relationship to AClass, regardless
of whether or not A and B are related. The common parent of AClass<A> and AClass is Object.
To establish sub-typing relationship, wildcard was introduced and is represented by the character ‘?’. Three versions of wildcard exist. Upper-bounded wildcard represents unknown types which is either a given type or its sub-type. Lower-bounded wildcard represents unknown types which is either a given type or its super-type. Unbounded wildcard represents any unknown types.
Compiler uses a technique called type erasure to convert generic types/methods to their non-generic counterpart. It generates just one class file which is used to create instances for all the type arguments. Although, Java generics is an extremely powerful tool,
it is not free from drawbacks. For example, we cannot specify primitive type arguments, cannot declare static fields of type parameters, cannot create instances of type parameters, cannot use instanceof, cannot create generic arrays etc.
WEB RESOURCES
http://docs.oracle.com/javase/tutorial/ java/generics/ Lesson: Generics http://www.eecs.qmul.ac.uk/~mmh/APD/bloch/ generics.pdf Generics http://cs.nyu.edu/courses/spring12/CSCI- GA.3033-014/generics-tutorial.pdfGenerics in the Java Programming Language
http://www.agiledeveloper.com/articles/ GenericsInJavaPartI.pdf
Generics in Java – Part I
http://userpages.umbc.edu/~edelman/341/ JavaGenerics.pdf
Java generics and Collections
EXERCISES
Objective-type Questions
1. Why are generics used?
(a) Generics make code more fast.
(b) Generics make code more optimized and readable.
(c) Generics add stability to your code by making more of your bugs detectable at compile time.
(d) Generics add stability to your code by making more of your bugs detectable at run time.
2. Which of these type parameters is used for a
generic class to return and accept any type of object?
(a) K (c) T (b) N (d) V
3. Which of these type parameters is used for a
generic class to return and accept a number? (a) K (c) T
(b) N (d) V
4. Which of these is a correct way of defining generic
class?
(a) class name(T1, T2, …, Tn) { /* … */ } (b) class name <T1, T2, …, Tn>{ /* … */ } (c) class name[T1, T2, ..., Tn] { /* … */ } (d) class name{T1, T2, …, Tn} { /* … */ }
5. Which of the following is an incorrect statement
regarding the use of generics and parameterized types in Java?
(a) Generics provide type safety by shifting more type checking responsibilities to the compiler.
(b) Generics and parameterized types eliminate the need for down casts when using Java Collections.
(c) When designing your own collections class (say, a linked list), generics and parameterized types allow you to achieve type safety with just a single class definition as opposed to defining multiple classes.
(d) All of the mentioned
6. Which of the following characters is used to
represent wildcard?
(a) ? (c) # (b) * (d) @
7. Which of the following is incorrect for class C and
interface I1 and I2?
(a) <T extends I1 & C & I2> (b) <T extends I2 & I1 & C> (c) <T super C & I1 & I2 (d) <T extends C & I1 & I2>
GENERIC PROGRAMMING 131
8. Which of the following variable declarations is
incorrect?
(a) List<Integer> li = new ArrayList<Integer>(); (b) List<? extends Number> ld = new
LinkedList<Double>();
(c) List<Number> ln = new ArrayList<>(); (d) List<Integer>[] a = new ArrayList
<Integer>[10];
9. Which of the following is incorrect?
(a) <T extends Number> (b) <Tsuper Number> (c) <? extends Number> (d) <? super Number>
10. Which of the following reference types cannot be
generic?
(a) Anonymous inner class (b) Interface
(c) Inner class
(d) All of the mentioned
11. Which of the following is incorrect?
(a) List<Interger> is a sub-type of List<Number> (b) List<? extends Integer> is a sub-type of
List<? extends Number>
(c) List<Integer> is a sub-type of List<?> (d) List<Number> is a sub-type of List
<? extends Number>
12. Which of the following represents an unbounded
wildcard?
(a) <? extends String> (b) <? super String> (c) ?
(d) <? extends Number>
13. What is the output of this program?
import java.util.*;
public class genericstack <E> { Stack <E> stk = new Stack <E>();
public void push(E obj) { stk.push(obj); } public E pop() { E obj = stk.pop(); return obj; } } class Output {
public static void main(String args[]) { genericstack <String> gs = new genericstack<String>(); gs.push("Hello"); System.out.println(gs.pop()); } } (a) H (b) Hello (c) Runtime Error (d) Compilation Error
14. What is the output of this program?
import java.util.*;
public class genericstack <E> { Stack <E> stk = new Stack <E>(); public void push(E obj) {
stk.push(obj); } public E pop() { E obj = stk.pop(); return obj; } } class Output {
public static void main(String args[]) { genericstack <Integer> gs = new
genericstack<Integer>(); gs.push(36); System.out.println(gs.pop()); } } (a) 0 (b) 36 (c) Runtime Error (d) Compilation Error
15. What is the output of this program?
import java.util.*;
public class genericstack <E> { Stack <E> stk = new Stack <E>(); public void push(E obj) {
stk.push(obj); } public E pop() { E obj = stk.pop(); return obj; } } class Output {
public static void main(String args[]) { genericstack <String> gs = new
genericstack<String>(); gs.push("Hello");
System.out.print(gs.pop() + " "); genericstack <Integer> gs = new genericstack<Integer>(); gs.push(36); System.out.println(gs.pop()); } } (a) Error (b) Hello (c) 36 (d) Hello 36
16. What is the output of this program?
import java.util.*;
public class genericstack <E> { Stack <E> stk = new Stack <E>(); public void push(E obj) {
stk.push(obj); } public E pop() { E obj = stk.pop(); return obj; } } class Output {
public static void main(String args[]) { genericstack <Integer> gs = new
genericstack<Integer>(); gs.push(36); System.out.println(gs.pop()); } } (a) H (b) Hello (c) Runtime Error (d) Compilation Error
17. Which syntax would you use to express a wildcard
with a lower-bound of some type? (a) ?
(b) ? extends type (c) ? super type (d) None of the above
18. Which syntax would you use to express a wildcard
with an upper-bound of some type? (a) ?
(b) ? extends type (c) ? super type (d) None of the above
19. When was generics first introduced in Java?
(a) JDK 1.4 (c) JDK 1.6 (b) JDK 1.5 (d) JDK 1.7
20. Which of the following character pairs are used to
write type parameters? (a) <> (c) [] (b) {} (d) ()
Subjective-type Questions
1. Briefly explain the concept of Java generics. 2. Write the primary purpose of Java generics. 3. Explain briefly the benefits of using Java
generics.
4. What is the benefit of Generics in Collections
Framework?
5. Why can’t we write code as List<Number>
numbers = new ArrayList<Integer>();?
6. Why can’t we create generic array, or
write code as List<Integer>[] array = new ArrayList<Integer>[10];?
7. Write a generic method to exchange the positions
of two different elements in an array.
8. How is a generic type instantiated (to form a
parameterized type)?
9. What is the raw type and what are its
usefulness?
10. Explain the concept of bounded type parameter. 11. Which specific problem does wildcard solve?
12. Explain with examples the different kinds of
wildcards.
13. Identify those types that cannot be used as type
arguments.
14. Briefly explain the concept of ‘type erasure’? 15. Will the following method compile? If not, why?
public static void print(List<? extends Number> list) {
for (Number n : list)
System.out.print(n + " "); System.out.println();
}
16. Given the following classes:
class Shape { /* ... */ }
class Circle extends Shape { /* ... */ } class Rectangle extends Shape { /* ... */ } class Node<T> { /* ... */ }
Will the following code compile? If not, why?
Node<Circle> nc = new Node<>(); Node<Shape> ns = nc;
17. Write the tasks performed by type erasure. 18. What is an “unchecked” warning message?
Reflection
K
eyO
bjectivesAfter completing this chapter readers will be able to— • understand the importance of reflection API
• examine and/or modify the properties or behaviour at run-time • familiarize with reflection classes and interfaces
• know how to write dynamic proxy • use annotations to analyze code • identify some drawbacks of reflection
7.1 INTRODUCTION
One of the reasons why Java language has been so powerful and widely used is due to some of its APIs such as reflection using which one can do a whole lot of unimaginable tasks. The reflection API in Java enables us to examine and/or modify the properties or behaviour or other elements of an object at run-time. For example, given a class name, we can extract all kinds of information about the class such as if it is public or abstract or final, fields and methods contained in that class, their modifiers, its super-class or even interface the class implements. This is possible even if the source code of the class is not available.
Understanding reflection a bit will help us understanding the tools (such as NetBeans, Eclipse, Spring) that use this API.
Most classes and interfaces to implement reflection are provided as a separate package java. lang.reflect except one java.lang.Class which is considered to be the primary reflection class.