Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG."— Presentation transcript:

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

2 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 syntax JDK 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

3 Java 5 overview 1.Generics 2.Auto Boxing and Un-boxing 3.Enhanced for-loop 4.Enumerations 5.Annotation 6.Variable arguments 7.Static imports 8.Other Enhancements

4 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

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

6 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 names = new Stack (); You can write methods that require a type-safe collection as follows: –void printNames (Stack names) { String nextName = names.pop(); // no casting needed! names.push("Hello"); // works just the same as before names.push(Color.RED); // compile-time error!

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

8 Defining Simple Generics Here is a small excerpt from the definitions of the interfaces List and Iterator in package java.util: public interface List { void add(E element); E get(int index); } public interface List { 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’

9 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 Animal Dog

10 Generics, Cont. What bout this code snippet 14:List strList = new ArrayList (); 15:List objList = strList; 16:objList.add(new Object()); 17:String s = strList.get(0); 14:List strList = new ArrayList (); 15:List objList = strList; 16:objList.add(new Object()); 17:String s = strList.get(0); 1. 1.Error at line 15: Cannot convert from list to list 2. 2.Error at line 16: Cannot add objects to list of Strings 3. 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.

11 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 ();  new Stack(); As a result, –You can still say: if (thing instanceof Stack)... –but you cannot say: if (thing instanceof Stack )...

12 void printCollection(Collection c) { for (Object e : c) { System.out.println(e); }  printCollection(new ArrayList ()); void printCollection(Collection c) { for (Object e : c) { System.out.println(e); }  printCollection(new ArrayList ()); Generic Wildcards Printing 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 as ArrayList Warning : Passing ArrayList as ArrayList is not type safe Success : 0 errors, 0 warnings void printCollection(Collection c) { for (Object e : c) { System.out.println(e); }  printCollection(new ArrayList ());  Okay. void printCollection(Collection c) { for (Object e : c) { System.out.println(e); }  printCollection(new ArrayList ());  Okay.

13 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 (); 2: c.add(new Object()); 3: c.add(null); 1: Collection c = new ArrayList (); 2: c.add(new Object()); 3: c.add(null); 1. 1.Error at line 1: Cannot instantiate unknown collection 2. 2.Error at line 2: Cannot add to an unknown collection 3. 3.Warninig at line 3: adding null to a collection is useless

14 Bounded Wildcard To restrict access to specific type of objects, you can bound the generic parameter: –Ex: Stricting access to numbers Double getAvg(Collection col) { } –Will accept any collection of any subclass of Number (Including Number it self) Remember the solution: –Double getAvg(Collection col) {} will not work, as it is expecting a List and it will not accept List for example

15 Generic Wildcards, Cont. The same restriction exists, you still can’t add values inside a collection declared using ‘?’. 1: void doSomeThing(Collection col) 2: {... 4:Col.add(new Number()); 5: } 1: void doSomeThing(Collection col) 2: {... 4:Col.add(new Number()); 5: } 1. 1.Error at line 4: Method add is not applicable for type ‘Number’ 2. 2.Success: 0 errors, 0 warnings

16 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 Solution, is to make that method a generic method as well. – Collection arrayToCollection(E [] elems,Collection col) { for(E x : elems){ col.add(x); return col; } }

17 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 parameter 1. compare (List a, List b) 2.Generic parameter used as a return type 1. T getMin (Collection 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 – void printAll (Collection x) == void printAll (Collection x)

18 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 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

19 Interoperating with Legacy Code-1 void doSomeThing1(Collection col) {... } 1: public static void main(String []args) 2: { 3: doSomeThing1(new ArrayList ()); 4: } void doSomeThing1(Collection col) {... } 1: public static void main(String []args) 2: { 3: doSomeThing1(new ArrayList ()); 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

20 Interoperating with Legacy Code-2 void doSomeThing1(Collection col) {... } void doSomeThing2(Collection col) {... } 1: public static void main(String []args) 2: { 3: doSomeThing1(new ArrayList()); 4: doSomeThing2(new ArrayList()); 5: } void doSomeThing1(Collection 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

21 More on Generics More than one generic type: – void myMethod (X a, Y b, Z c); The use of more than one upper bound –void myMethod (Collection ) The use of lower bound –void myMethod (Collection ) Explicitly inferring generic type –Collections. unmodifiableSet(set);

22 Generics support in Eclipse 3.1 Quick Fix features Quick fix suggest a solution

23 Refactor  Infer Generic Type Argument… Generics support in Eclipse 3.1

24 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 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))); Generics support in Eclipse 3.1

25 Eclipse has gotten smart about finding generic references The filter menu of the search window allows you to filter generics-aware results

26 Limitations 1:class AClass extends T { 2:private static Collection 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 (); 10:List [] s = new ArrayList [9]; 11:Collection c = new ArrayList (); 12: c.add(new Object()); 13:class MyList implements MyCollection, 14:MyCollection { } 1:class AClass extends T { 2:private static Collection 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 (); 10:List [] s = new ArrayList [9]; 11:Collection c = new ArrayList (); 12: c.add(new Object()); 13:class MyList implements MyCollection, 14:MyCollection { } } } Legend: Success Warning Error

27 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 ”, HereHere “Generics Considered Harmful”, same source, HereHere “ Generics are a mistake. ”, Ken A rnold, the creator of Jini, JavaSpaces, Curses, and Rogue, HereHere “ it's not the idea of generics that is the problem, but the implementation ”, Same source

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

29 References Sun Microsystems Generic tutorial http://java.sun.com/j2se/1.5/pdf/g enerics-tutorial.pdf


Download ppt "Java 1.5 Generics Amr Ali Software Engineer, IBM-Egypt EG-JUG."

Similar presentations


Ads by Google