java 1.5 generics amr ali software engineer, ibm-egypt eg-jug

29
Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG EG-JUG

Upload: brittany-wheeler

Post on 19-Jan-2016

219 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Java 1.5 Generics

Amr Ali

Software Engineer, IBM-Egypt

EG-JUGEG-JUG

Page 2: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Versions of Java

Java 1

Java 2

Java 5.0

Oak: Designed for embedded devices

Java: Original, not very good version (but it had applets)

JDK 1.2: Includes “Swing” but no new syntaxJDK 1.3: Additional methods and packages, but no new syntax

JDK 1.4: More additions and the assert statement

JDK 1.5: Generics, enums, new for loop, and other new syntax

JDK 1.1: Adds inner classes and a completely new event-handling model

pre-Java

Page 3: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Java 5 overview1. Generics2. Auto Boxing and Un-boxing3. Enhanced for-loop4. Enumerations5. Annotation6. Variable arguments7. Static imports8. Other Enhancements

Page 4: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Motivations• In Java, array elements must all be of the same type:

– int[] counts = new int[10];• Hence, arrays are type safe: The compiler will not

let you put the wrong kind of thing into an array• A collection, such as a Vector or ArrayList, cannot

hold primitives, but will accept any type of Object:– Stack someStuff = new Stack();

someStuff.push("A String is an Object");someStuff.push(Color.BLUE);

• Is not type safe

Page 5: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Motivations, Cont.• Making a collection type safe is a tedious process

class StackOfStrings {private Stack internalStack = new Stack();public boolean isEmpty() { return internalStack.isEmpty();}public String push(String s) { internalStack.push(s); return s;}public String pop() { return(String)internalStack.pop();} etc.

class StackOfStrings {private Stack internalStack = new Stack();public boolean isEmpty() { return internalStack.isEmpty();}public String push(String s) { internalStack.push(s); return s;}public String pop() { return(String)internalStack.pop();} etc.

Page 6: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generics for type safety in Java 5

• In Java 5, you can easily make any collection type safe• For example, you can create a Stack that holds only

Strings as follows:– Stack<String> names = new Stack<String>();

• You can write methods that require a type-safe collection as follows:– void printNames (Stack<String> names) {

• String nextName = names.pop(); // no casting needed!

• names.push("Hello"); // works just the same as before

• names.push(Color.RED); // compile-time error!

Page 7: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

What generics are and aren’t

In JDK 1.4:-

myStack = new Stack();•String s = myStack.pop(); will not compile•String s = (String)myStack.pop(); compiles, with runtime check•myStack.push(Color.RED); compiles with no complaint

In JDK 1.5:-

myStack = new Stack<String>();•String s = myStack.pop(); Compiles with NO runtime check Does not compile if myStack was declared any other way•myStack.push(Color.RED) is a compiler error (= syntax error)

Page 8: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Defining Simple Generics

• Here is a small excerpt from the definitions of the interfaces List and Iterator in package java.util:

public interface List <E> {void add(E element);E get(int index);

}

public interface List <E> {void add(E element);E get(int index);

}Indicates a generic class declaration

Method “add” accept parameter

of type ‘E’

Mehtod ‘get’ returns object of

type ‘E’

Page 9: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

A dog in the cat collection!

If a Collection of Cats were to inherit from Collection of Animals, then you may add a Dog (as an animal) to the Cats Collection, which is very Dangerous

Animal

Collection < Cat >

Collection < Animal >

Cat

Animal

Dog

Page 10: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generics, Cont.• What bout this code snippet

14: List<String> strList = new ArrayList<String>(); 15: List<Object> objList = strList;16: objList.add(new Object());17: String s = strList.get(0);

14: List<String> strList = new ArrayList<String>(); 15: List<Object> objList = strList;16: objList.add(new Object());17: String s = strList.get(0);

1. Error at line 15: Cannot convert from list<String> to list <Object>

2. Error at line 16: Cannot add objects to list of Strings

3. Error at line 17: Type mismatch, trying to Pop Object as String

• Java compiler will prevent any action that may violate the type safety rules or threaten your application stability.

Page 11: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generics, Behind the scene• Generics are implemented by the Java compiler

as a front-end conversion called erasure.• You can (almost) think of it as a source-to-

source translation, whereby the generic version of any method is converted to the non-generic version.

• Behind the scene, JavaC removes all type information:– e.g. new Stack<String>(); new Stack();

• As a result,– You can still say: if (thing instanceof Stack) ...– but you cannot say:

if (thing instanceof Stack<String>) ...

Page 12: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

void printCollection(Collection<Object> c) {

for (Object e : c) {

System.out.println(e);

}

}

printCollection(new ArrayList<String>());

void printCollection(Collection<Object> c) {

for (Object e : c) {

System.out.println(e);

}

}

printCollection(new ArrayList<String>());

Generic WildcardsPrinting contents of any generic collection:

Will accept only list of Objects

To accept any type of collection regardless its generic type, use “Collection<?> c” notation, means c is a collection of unknown type.

• Error : Cannot pass ArrayList<String> as ArrayList<Object>• Warning : Passing ArrayList<String> as ArrayList<Object> is

not type safe• Success : 0 errors, 0 warnings

void printCollection(Collection<?> c) {for (Object e : c) {

System.out.println(e);}

} printCollection(new ArrayList<String>()); Okay.

void printCollection(Collection<?> c) {for (Object e : c) {

System.out.println(e);}

} printCollection(new ArrayList<String>()); Okay.

Page 13: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generic Wildcards, Cont.

• Wildcards seemed to be powerful, but..– You cannot add elements to a collection declared using

wildcards, except ‘null’!• On the other hand, given a List<?>, we can call get() and

make use of the result.• The result type is an unknown type, but we always know that it

is an object.• You won’t be able to extract no thing but Object from a

collection declared using wild cards.

1: Collection<?> c = new ArrayList<String>();2: c.add(new Object());3: c.add(null);

1: Collection<?> c = new ArrayList<String>();2: c.add(new Object());3: c.add(null);

1. Error at line 1: Cannot instantiate unknown collection

2. Error at line 2: Cannot add to an unknown collection

3. Warninig at line 3: adding null to a collection is useless

Page 14: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Bounded Wildcard• To restrict access to specific type of

objects, you can bound the generic parameter:– Ex: Stricting access to numbers

• Double getAvg(Collection<? extends Number> col) { }

– Will accept any collection of any subclass of Number (Including Number it self)

• Remember the solution:– Double getAvg(Collection<Number> col) {} will not

work, as it is expecting a List<Number> and it will not accept List<Float> for example

Page 15: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generic Wildcards, Cont.

• The same restriction exists, you still can’t add values inside a collection declared using ‘?’.

1: void doSomeThing(Collection <? extends Number> col)2: {

...4: Col.add(new Number());5: }

1: void doSomeThing(Collection <? extends Number> col)2: {

...4: Col.add(new Number());5: }

1. Error at line 4: Method add is not applicable for type ‘Number’

2. Success: 0 errors, 0 warnings

Page 16: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generic methods• Consider writing a method that takes an array of

objects and a collection and puts all objects in the array into the collection.– It won’t work with Collection <?>– It will be tedious to use Collection <Object>

• Solution, is to make that method a generic method as well.– <E> Collection<E> arrayToCollection(E [] elems,Collection

<E> col) { for(E x : elems){

col.add(x);return col;

}}

Page 17: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generic methods, Cont.• We should now ask, When to use generic wildcards

and when to use generic method.– Use generic method in the following situations

1. Generic parameter appeared in more than one parameter1. <T> compare (List<T> a, List<T> b)

2. Generic parameter used as a return type1. <T extends Comparable > T getMin (Collection <T> col)

– Generally:• Generic methods allow type parameters to be used to express

dependencies among the types of one or more arguments to a method and/or its return type.

• If there isn’t such a dependency, a generic method should not be used.

• It is a sign to use wild card if the generic argument appeared only once in the method signature or body

– <T> void printAll (Collection <T> x) == void printAll (Collection <?> x)

Page 18: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

static void  overloadedMethod ( Object o) {        System.out.println(" overloadedMethod (Object) called");}static void overloadedMethod( String s) {        System.out.println(" overloadedMethod ( String) called ");}static void  overloadedMethod ( Integer i) {        System.out.println(" overloadedMethod ( Integer) called ");}

static <T> void genericMethod(T t) {         overloadedMethod (t) ;       // which method is called? }

public static void main(String[] args) {         genericMethod ( "abc" ); }

static void  overloadedMethod ( Object o) {        System.out.println(" overloadedMethod (Object) called");}static void overloadedMethod( String s) {        System.out.println(" overloadedMethod ( String) called ");}static void  overloadedMethod ( Integer i) {        System.out.println(" overloadedMethod ( Integer) called ");}

static <T> void genericMethod(T t) {         overloadedMethod (t) ;       // which method is called? }

public static void main(String[] args) {         genericMethod ( "abc" ); }

• Output:

• overloadedMethod (Object) called

• overloadedMethod ( String) called

• overloadedMethod ( Integer) called

Page 19: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Interoperating with Legacy Code-1

void doSomeThing1(Collection col){

...}1: public static void main(String []args)2: {3: doSomeThing1(new ArrayList<String>());4: }

void doSomeThing1(Collection col){

...}1: public static void main(String []args)2: {3: doSomeThing1(new ArrayList<String>());4: }

• Interoperating with legacy code was taken into consideration, you still can pass a generic collection to a methods that expects row collection safly

• Line 3:

• Error: Cannot pass a generic collection as row collection

• Warning: Passing generic collection as row collection is not type safe

• Success: 0 errors, 0 warnings

Page 20: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Interoperating with Legacy Code-2

<T> void doSomeThing1(Collection <T> col){

...}void doSomeThing2(Collection <?> col){

...}1: public static void main(String []args)2: {3: doSomeThing1(new ArrayList());4: doSomeThing2(new ArrayList());5: }

<T> void doSomeThing1(Collection <T> col){

...}void doSomeThing2(Collection <?> col){

...}1: public static void main(String []args)2: {3: doSomeThing1(new ArrayList());4: doSomeThing2(new ArrayList());5: }

• Line 3:

• Error: Cannot pass a row collection as generic

• Warning: Passing row collection as generic is not type safe

• Success: 0 errors, 0 warnings

• Passing a row collection to a method that expect generic collection will issue a type safety warning.

• Warning disappear when using wildcards

• Line 4:

• Error: Cannot pass a row collection as generic

• Warning: Passing row collection as generic is not type safe

• Success: 0 errors, 0 warnings

Page 21: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

More on Generics• More than one generic type:

– <X,Y, Z> void myMethod (X a, Y b, Z c);

• The use of more than one upper bound– void myMethod (Collection <T extends A &

B>)

• The use of lower bound– void myMethod (Collection <? super T>)

• Explicitly inferring generic type– Collections.<String> unmodifiableSet(set);

Page 22: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Generics support in Eclipse 3.1

• Quick Fix features

• Quick fix suggest a solution

Page 23: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

• Refactor Infer Generic Type Argument…

Generics support in Eclipse 3.1

Page 24: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

• Old Code:

• Updated code

• List empList = new ArrayList (5); empList.add(new Employee("Homer", 200.0, 1995));empList.add(new Employee("Lenny", 300.0, 2000));empList.add(new Employee("Waylon", 700.0, 1965)); empList.add(new Manager("Monty", 2000.0, 1933, empList.get(2)));

• List empList = new ArrayList (5); empList.add(new Employee("Homer", 200.0, 1995));empList.add(new Employee("Lenny", 300.0, 2000));empList.add(new Employee("Waylon", 700.0, 1965)); empList.add(new Manager("Monty", 2000.0, 1933, empList.get(2)));

• List<Employee> empList = new ArrayList<Employee>(5); empList.add(new Employee("Homer", 200.0, 1995));empList.add(new Employee("Lenny", 300.0, 2000));empList.add(new Employee("Waylon", 700.0, 1965)); empList.add(new Manager("Monty", 2000.0, 1933, empList.get(2)));

• List<Employee> empList = new ArrayList<Employee>(5); empList.add(new Employee("Homer", 200.0, 1995));empList.add(new Employee("Lenny", 300.0, 2000));empList.add(new Employee("Waylon", 700.0, 1965)); empList.add(new Manager("Monty", 2000.0, 1933, empList.get(2)));

Generics support in Eclipse 3.1

Page 25: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

• Eclipse has gotten smart about finding generic references

• The filter menu of the search window allows you to filter generics-aware results

Page 26: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Limitations1: class AClass<T> extends T {

2: private static Collection<T> myCol2;

3: Private static T myMethod() {}

4: public static void aMethod(Object arg) {

5: if(arg instanceof T) {}

6: T var = new T();

7: T[] array = new T[100];

8: T[] array = (T)new Object[SIZE];

9: ArrayList x = new ArrayList<int>();

10: List <String> [] s = new ArrayList <String> [9];

11: Collection<?> c = new ArrayList<String>();

12: c.add(new Object());

13: class MyList implements MyCollection<Integer>,

14: MyCollection <Double>

{

}

}

}

1: class AClass<T> extends T {

2: private static Collection<T> myCol2;

3: Private static T myMethod() {}

4: public static void aMethod(Object arg) {

5: if(arg instanceof T) {}

6: T var = new T();

7: T[] array = new T[100];

8: T[] array = (T)new Object[SIZE];

9: ArrayList x = new ArrayList<int>();

10: List <String> [] s = new ArrayList <String> [9];

11: Collection<?> c = new ArrayList<String>();

12: c.add(new Object());

13: class MyList implements MyCollection<Integer>,

14: MyCollection <Double>

{

}

}

}

Legend:Legend: SuccessSuccess WarningWarning ErrorError

Page 27: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

People’s opinion…• “Generics are probably the most long awaited addition to the

Java language. “ Neal Ford – Application Architect• “Why do we have erasure?, They prevent ClassCastExceptions.

How big of a problem is this, versus the overhead of (1) learning and (2) maintaining the code of the new syntax of the feature “Bruce Eckel ,Author of “Thinking in Java”, Here

• “Generics Considered Harmful” , same source, Here

• “Generics are a mistake. ”, Ken Arnold, the creator of Jini, JavaSpaces, Curses, and Rogue , Here

• “it's not the idea of generics that is the problem, but the implementation ”, Same source

Page 28: Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG

Conclusion• Generics were developed to provide type-

safety. • They accomplish that goal to a certain

degree. However, they don’t provide type-safety to the full extent. This is largely due to the design goals and implementation constraints.

• First learn Generics in Java. Then have the wisdom to decide when and how (much) to use it.