java - generic programming

25
GENERIC PROGRAMMING PROGRAMMAZIONE CONCORRENTE E DISTR. Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in Informatica, A.A. 2015 – 2016 [email protected]

Upload: riccardo-cardin

Post on 09-Feb-2017

734 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Java - Generic programming

GENERIC PROGRAMMINGPROGRAMMAZIONE CONCORRENTE E DISTR.Università degli Studi di Padova

Dipartimento di Matematica

Corso di Laurea in Informatica, A.A. 2015 – [email protected]

Page 2: Java - Generic programming

2Programmazione concorrente e distribuita

SUMMARY Introduction Generic classes and methods Type variables bounds Type erasure Restrictions and limitations Generics and inheritance Wildcard types

Riccardo Cardin

Page 3: Java - Generic programming

3Programmazione concorrente e distribuita

INTRODUCTION Generic programming means writing code that can

be reused for object of many different typesAdded to the JDK from version 5.0

It tooks 5 years to be formalized (from 1999) First added to support strongly typed collections (as in C++)

No generic code is obscure and not typesafe

Before generics there was no typesafe checking Errors will be find only at runtime Violation of FAIL FAST principle

Riccardo Cardin

// Before generic classesArrayList files = new ArrayList();// You do not know which kind of object are store inside the listString filename = (String) files.get(0);

Page 4: Java - Generic programming

4Programmazione concorrente e distribuita

INTRODUCTION Generics solution: type parameters

The compiler can perform typesafe checks

Generics make the code safer and easier to read But how will you use generic programming?

Basic level: just use generic classes Intermediate level: when you encounter your first

enigmatic error using generic classesAdvanced level: implement your own generic classes

Riccardo Cardin

// After generic classesArrayList<String> files = new ArrayList<>();// You do not need the cast operation anymoreString filename = files.get(0);

Page 5: Java - Generic programming

5Programmazione concorrente e distribuita

INTRODUCTION

Riccardo Cardin

Page 6: Java - Generic programming

6Programmazione concorrente e distribuita

GENERIC CLASSES A class with one or more type variable

Type variable are introduced after class name, enclosed by angle brackets < > Type variables are used throughout the class definition

It is common to use upper case letters for type variablesA type variables is instantiated by substituting types

Generic classes act as a factory for ordinary classes

Riccardo Cardin

class Pair<T, U> { private T first; private U second; // ...}

Pair<Integer, String> pair = new Pair<>();Integer first = pair.getFirst();String second = pair.getSecond();

Page 7: Java - Generic programming

7Programmazione concorrente e distribuita

GENERIC METHODS Also single methods can be defined as generics

Type variable definition stands behind method’s return type

Can be placed inside both generic an ordinary classesYou can omit the type variable instantiation

But sometimes the compiler gets it wrong...

Which type is inferred by the compiler? Number!!! In C++, type parameters are after method name

This can lead to ambiguitesRiccardo Cardin

public static <T> T getMiddle(T... a) { /* ... */ }String middle = getMiddle("Riccardo", "Cardin", "Professor");

double middle = ArrayAlg.getMiddle(3.14, 1729, 0);

Page 8: Java - Generic programming

8Programmazione concorrente e distribuita

TYPE VARIABLES BOUNDS Rescriction of a type variable to a class that is a

subtype of an another type

Use extends keyword both for classes and interfaces It is possibile to use multiple bounds

At most one bound can be a classRiccardo Cardin

class ArrayAlg { public static <T extends Comparable> T min(T[] a) { if (a == null || a.length == 0) return null; T smallest = a[0]; for (int i = 1; i < a.length; i++) // We know for sure that compareTo is available if (smallest.compareTo(a[i]) > 0) smallest = a[i]; return smallest; } }

T extends Comparable & Serializable

Page 9: Java - Generic programming

9Programmazione concorrente e distribuita

TYPE ERASURE The JVM does not have objects of generic types

Type variables are erased and replaced with bounding variables or Object type if it ain’t any For each generic type a raw type is provided automatically

Casts are inserted if necessary to preserve type safetyBridge methods are generated to preserve

polymorphismNo new class are created for parametrized typesRiccardo Cardin

// Remember generic class Pair<T, U> ?class Pair { private Object first; private Object second; // ...}

Page 10: Java - Generic programming

10Programmazione concorrente e distribuita

TYPE ERASURE Translating generic expression

Compiler inserts casts when the return the return type has been erased

Translating generic methodsA generic method is not a family of methods

This fact has a series of implications... Riccardo Cardin

Pair<Employee, Salary> buddies = /* ... */;Employee buddy = buddies.getFirst();// After type erasure will becomePair buddies = /* ... */;Employee buddy = (Employee) buddies.getFirst(); // Returns an Object

public static <T extends Comparable> T min(T[] a)// becomes after type erasurepublic static Comparable min(Comparable[] a)

Page 11: Java - Generic programming

11Programmazione concorrente e distribuita

TYPE ERASURE Translating generic methods

Type erasure interferes with polymorphism, then the compiler generates synthetic bridge methods

Riccardo Cardin

public class Node<T> { public T data; public Node(T data) { this.data = data; } public void setData(T data) { System.out.println("Node.setData"); this.data = data; }}public class MyNode extends Node<Integer> { public MyNode(Integer data) { super(data); } @Override public void setData(Integer data) { System.out.println("MyNode.setData"); super.setData(data); }}

Page 12: Java - Generic programming

12Programmazione concorrente e distribuita

TYPE ERASURE Translating generic methods

After type erasure setData method has wrong type and cannot override parent method

Riccardo Cardin

public class Node { public Object data; public Node(Object data) { this.data = data; } public void setData(Object data) { System.out.println("Node.setData"); this.data = data; }}public class MyNode extends Node { public MyNode(Integer data) { super(data); } // Not polymorphic anymore :O public void setData(Integer data) { System.out.println("MyNode.setData"); super.setData(data); }}

Page 13: Java - Generic programming

13Programmazione concorrente e distribuita

TYPE ERASURE Translating generic methods

Compiler insert a bridge method that overrides the parent method, resolving subtyping Delegation design pattern

There are cases that are stanger The type parameters appears only in method return type

Riccardo Cardin

class MyNode extends Node { // Bridge method generated by the compiler public void setData(Object data) { setData((Integer) data); } // ...

class DateInterval extends Pair<Date> { public Date getSecond() { return (Date) super.getSecond().clone(); }}

Let’s try it yourself

Page 14: Java - Generic programming

14Programmazione concorrente e distribuita

TYPE ERASURE

Riccardo Cardin

Page 15: Java - Generic programming

15Programmazione concorrente e distribuita

RESTRICTIONS AND LIMITATIONS Type Parameters Cannot Be Instantiated with

Primitive Types Runtime Type Inquiry Only Works with Raw Types You Cannot Create Arrays of Parameterized Types Varargs Warnings... You Cannot Instantiate Type Variables Type Variables Are Not Valid in Static Contexts of

Generic Classes You Cannot Throw or Catch Instances of a Generic

Class Beware of Clashes after Erasure

Riccardo Cardin

Page 16: Java - Generic programming

16Programmazione concorrente e distribuita

GENERICS AND INHERITANCE Generics and inheritance works togheter in an

unintuitive way In general, there is no relationship between Pair<S>

and Pair<T>, no matter how S and T are related Necessary for type safety

Generics are said invariant

Riccardo Cardin

// Type safety restrictionPair<Manager> managerBuddies = new Pair<>(ceo, cfo);// Illegal, but suppose it // wasn'tPair<Employee> employeeBuddies = managerBuddies; employeeBuddies.setFirst( lowlyEmployee);

Page 17: Java - Generic programming

17Programmazione concorrente e distribuita

GENERICS AND INHERITANCE Unfortunately there is a way to bypass this type

safety controls

But, this is the same behaviour we obtain using older version of Java (≤ 1.5) NEVER use raw type of generics if you can

Generic classes can extend or implement other generic types For example, ArrayList<T> implements List<T>

So, an ArrayList<Manager> is subtype of List<Manager>

Riccardo Cardin

Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);Pair rawBuddies = managerBuddies; // OK// Only a compile-time warning. A ClassCastException // is thrown at runtimerawBuddies.setFirst(new File(". . ."));

Page 18: Java - Generic programming

18Programmazione concorrente e distribuita

WILDCARD TYPES The type system derived is too rigid: wildcard

types help to safetly relax some constraint

Why using wildcard types can we force type safety? The compiler cannot guess the real type the object passed

Use wildcard type as return types in methods In return types the compiler needs only to know which is the

supertype, to allow assignments Type ? extends T is said covariant wrt type T

Riccardo Cardin

// Any generic Pair whose type parameter is a subclass of EmployeePair<? extends Employee>

Pair<Manager> managerBuddies = new Pair<>(ceo, cfo);Pair<? extends Employee> wildcardBuddies = managerBuddies; // OKwildcardBuddies.setFirst(lowlyEmployee); // compile-time error

Page 19: Java - Generic programming

19Programmazione concorrente e distribuita

WILDCARD TYPES

Riccardo Cardin

Page 20: Java - Generic programming

20Programmazione concorrente e distribuita

WILDCARD TYPES How can we use wildcard type for parameters?

In Java are available supertype bounds

A wildcard with a super type bound gives you a behavior that is opposite to that of the wildcards

You can supply parameters to methods, but you can’t use the return values

As a return values the only possible assignee type is Object Type ? super T is said contravariant wrt type T Riccardo Cardin

// Any generic Pair whose type parameter is restricted to all // supertypes of ManagerPair<? super Manager>

// Any generic Pair whose type parameter is restricted to all // supertypes of ManagerPair<? super Manager>

Page 21: Java - Generic programming

21Programmazione concorrente e distribuita

WILDCARD TYPES

Riccardo Cardin

Page 22: Java - Generic programming

22Programmazione concorrente e distribuita

WILDCARD TYPES You can even use wildcards with no bounds

As a return value, can only be assigned to an Object As a parameter, no type matches, not even Object

A method with a parameter with an unbounded wildcard type can never be called Actually, you can call it passing a null reference...

Remember, an unbounded wildcard is not a type So you can not use it when a type is requested

Riccardo Cardin

// It is different from the raw type PairPair<?>

// This code is not valid, use type variables instead? t = p.getFirst(); // ERRORp.setFirst(p.getSecond());p.setSecond(t);

Page 23: Java - Generic programming

23Programmazione concorrente e distribuita

WILDCARD TYPES

Riccardo Cardin

Page 24: Java - Generic programming

24Programmazione concorrente e distribuita

EXAMPLES

Riccardo Cardin

https://github.com/rcardin/pcd-snippets

Page 25: Java - Generic programming

25Programmazione concorrente e distribuita

REFERENCES Chap. 12 «Generic Programming», Core Java Volume I -

Fundamentals, Cay Horstmann, Gary Cornell, 2012, Prentice Hall Chap. 6 «Generic Programming», Core Java for the Impatient, Cay

Horstmann, 2015, Addison-Wesley Type Erasure

https://docs.oracle.com/javase/tutorial/java/generics/erasure.html Effects of Type Erasure and Bridge Methods https://

docs.oracle.com/javase/tutorial/java/generics/bridgeMethods.html Covariance and Contravariance In Java

https://dzone.com/articles/covariance-and-contravariance Covariance, Invariance and Contravariance explained in plain

English? http://stackoverflow.com/questions/8481301/covariance-invariance-and-contravariance-explained-in-plain-english

Riccardo Cardin