Advanced Programming in Java GenericParameterized Types Mehdi Einali

  • Slides: 50
Download presentation
Advanced Programming in Java Generic(Parameterized ) Types Mehdi Einali 1

Advanced Programming in Java Generic(Parameterized ) Types Mehdi Einali 1

Agenda Why Generics Generic Methods Generic Classes Type Erasure Generics and Inheritance Generics and

Agenda Why Generics Generic Methods Generic Classes Type Erasure Generics and Inheritance Generics and Wild Cards Restrictions on Generics 2

Why generics 3

Why generics 3

Stack interfaces interface String. Stack{ void push(String s); String pop(); } interface Integer. Stack{

Stack interfaces interface String. Stack{ void push(String s); String pop(); } interface Integer. Stack{ void push(Integer s); Integer pop(); } interface Student. Stack{. . . 4

Sort Method static void //. . . } sort(Integer[] array) { sort(Double[] array) {

Sort Method static void //. . . } sort(Integer[] array) { sort(Double[] array) { sort(String[] array) { sort(Student[] array){ 5

The Problem What is wrong with these examples? Code redundancy No effective code reuse

The Problem What is wrong with these examples? Code redundancy No effective code reuse Solution? Using Object class Pros and Cons? Compile-time type safety 6

Compile time vs runtime Compile Runtime Most of time Common properties and controls required

Compile time vs runtime Compile Runtime Most of time Common properties and controls required But software is not just execution of code developers is very important Annotations: @Deprecated, @Override, @Author We need some type check just for compile time(for humans not computers) 7

The Solution Generic types and methods Methods with similar implementation which accepts parameters for

The Solution Generic types and methods Methods with similar implementation which accepts parameters for impose some restriction on them Generics provides abstraction over Types (Parameterized Types) 8

Generic stack Stack<Havij> stack=new Stack<Havij>(); Stack. push(new Havij()); Stack<Golabi> stack=new Stack<Golabi>(); Stack. push(new Golabi());

Generic stack Stack<Havij> stack=new Stack<Havij>(); Stack. push(new Havij()); Stack<Golabi> stack=new Stack<Golabi>(); Stack. push(new Golabi()); 9

Why generics? To enable a compiler to as much as error as it can

Why generics? To enable a compiler to as much as error as it can at compile time rather than getting surprised at run time (e. g. Class. Cast. Exception) Extended code reusability Improve readability and robustness Try to find bugs ASAP!! 10

Generic classes 11

Generic classes 11

Type parameter as the Return Type interface Stack<T>{ void push(T s); T pop(); }

Type parameter as the Return Type interface Stack<T>{ void push(T s); T pop(); } Stack<String> string. Stack = new. . . string. Stack. push(“salam”); String s = string. Stack. pop(); 12

public class Stack<E > { private E[] elements ; private final int size; //

public class Stack<E > { private E[] elements ; private final int size; // number of elements in the stack private int top; // location of the top element public void push(E push. Value) { if (top == size - 1) // if stack is full throw new Full. Stack. Exception(); elements[++top] = push. Value; } public E pop() { if (top == -1) // if stack is empty throw new Empty. Stack. Exception(); return elements[top--]; } public Stack() { size = 10; top = -1; elements = new Object[size]; } } 13

Using Stack Class Stack<String> stack 1 = new Stack<String>(); stack 1. push("first"); stack 1.

Using Stack Class Stack<String> stack 1 = new Stack<String>(); stack 1. push("first"); stack 1. push("second"); System. out. println(stack 1. pop()); Stack<Integer> stack 2 = new Stack<>(); stack 2. push(1); stack 2. push(2); System. out. println(stack 2. pop()); 14 Since V 7 Diamond

Compile-time Type Checking Stack<String> stack 1 = new Stack<String>(); stack 1. push(new Integer(2)); Compile-time

Compile-time Type Checking Stack<String> stack 1 = new Stack<String>(); stack 1. push(new Integer(2)); Compile-time error 15

public class Stack<E extends Student> { private E[] elements ; private final int size;

public class Stack<E extends Student> { private E[] elements ; private final int size; // number of elements in the stack private int top; // location of the top element public void push(E push. Value) { if (top == size - 1) // if stack is full throw new Full. Stack. Exception(); elements[++top] = push. Value; } public E pop() { if (top == -1) // if stack is empty throw new Empty. Stack. Exception(); return elements[top--]; } public Stack() { size = 10; top = -1; elements = new Student[size]; } } 16

Naming Conventions By convention, type parameter names are single, uppercase letters The most commonly

Naming Conventions By convention, type parameter names are single, uppercase letters The most commonly used type parameter names are: E - Element (used extensively by the Java Collections Framework) K - Key N - Number T - Type V - Value S, U, V etc. - 2 nd, 3 rd, 4 th types 17

Generic methods 18

Generic methods 18

Generic Methods Declaring a method which accepts different parameter types Type Parameter It says:

Generic Methods Declaring a method which accepts different parameter types Type Parameter It says: In this method, E is not a regular type, it is a generic one For each method invocation, the compiler searches the appropriate method If the compiler does not find a method, it looks for a compatible generic method 19

print. Array() Generic Method 20

print. Array() Generic Method 20

Benefits of Generics public static < E extends Number> void print. Array( E[] input.

Benefits of Generics public static < E extends Number> void print. Array( E[] input. Array ){…} Restricting possible types Compile-time type checking print. Array(string. Array) brings Compiler Error or exception? 21

You can specify generic type for methods too. 22

You can specify generic type for methods too. 22

Type erasure 23

Type erasure 23

Raw Types Generic classes and methods can be used without type parameter Stack<String> s

Raw Types Generic classes and methods can be used without type parameter Stack<String> s = new Stack<String>(); String as type parameter s. push(“salam”); s. push(new Integer(12)); Compiler Error Stack object. Stack = new Stack(); no type parameter s. push(“salam”); s. push(new Integer(12)); s. push(new Student(“Ali Alavi”)); 24

No Generics in Runtime Generics is a compile-time aspect In runtime, there is no

No Generics in Runtime Generics is a compile-time aspect In runtime, there is no generic information All generic classes and methods are translated with raw types Byte code has no information about generics Only raw types in byte code This mechanism is named generic type erasure 25

Erasure Example (1) class Stack<T>{ void push(T s){. . . } T pop() {.

Erasure Example (1) class Stack<T>{ void push(T s){. . . } T pop() {. . . } } Is translated to class Stack { void push(Object s){. . . } Object pop() {. . . } } 26

Erasure Example (2) Translated to 27

Erasure Example (2) Translated to 27

What Happens if… 28

What Happens if… 28

Some Notes We can also create generic interfaces interface Stack<T>{ void push(T s); T

Some Notes We can also create generic interfaces interface Stack<T>{ void push(T s); T pop(); } 29

What Happens if… public static <E extends Number> void f(E i){ } public static

What Happens if… public static <E extends Number> void f(E i){ } public static void f(Number i){ } Compiler Error : Method f(Number) has the same erasure version f(Number) as another method in this type 30

Multiple Type Parameters class Multiple. Type<T, K>{ private T t; public T get. T()

Multiple Type Parameters class Multiple. Type<T, K>{ private T t; public T get. T() { return t; } public void set. T(T t) { this. t = t; } public void do. Somthing(K k, T t){…} } Multiple. Type<String, Integer> multiple = new Multiple. Type<String, Integer>(); multiple. do. Somthing(5, "123"); 31

Inheritance and generics 32

Inheritance and generics 32

Generics and subtypes You can do this Object o = new Integer(5); You can

Generics and subtypes You can do this Object o = new Integer(5); You can even do this Object[] or = new Integer[5]; So you would expect to be able to do this Array. List<Object> ao = new Array. List<Integer>(); This is counter-intuitive at the first glance 33

Why? So there is no inheritance relationship between type arguments of a generic class

Why? So there is no inheritance relationship between type arguments of a generic class in assignment 34

This works Inheritance relationship between generic classes themselves still exists 35

This works Inheritance relationship between generic classes themselves still exists 35

Still works Entries in a collection maintain inheritance relationship 36

Still works Entries in a collection maintain inheritance relationship 36

Generics and Inheritance A non-generic class can be inherited by a nongeneric class As

Generics and Inheritance A non-generic class can be inherited by a nongeneric class As we saw before learning generics A generic class can be inherited from a non-generic class Adding generality to classes A non-generic class can be inherited from a generic class Removing generality A generic class can be inherited by a generic class 37

class Generic. List<T> extends Object{ public void add(T t){. . . } public T

class Generic. List<T> extends Object{ public void add(T t){. . . } public T get(int i) {. . . } public void remove(int i) {. . . } } class Generic. Numeric. List<T extends Number> extends Generic. List<T>{ } class Non. Zero. Integer. List extends Generic. List<Integer>{ public void add(Integer t) { if(t==null || t==0) throw new Runtime. Exception(“Bad value"); super. add(t); } } 38

Generics and Wild card 39

Generics and Wild card 39

Why Wildcards? Problem Consider the problem of writing a routine that prints out all

Why Wildcards? Problem Consider the problem of writing a routine that prints out all the elements in a collection What is wrong with this? 40

Why Wildcards? Solution Use Wildcard type argument <? > Collection<? > means Collection of

Why Wildcards? Solution Use Wildcard type argument <? > Collection<? > means Collection of unknown type 41

Bounded wild character If you want to bound the unknown type to be a

Bounded wild character If you want to bound the unknown type to be a subtype of another type, use bounded Wildcard 42

Restrictions on generic types 43

Restrictions on generic types 43

Not primitive type Cannot Instantiate Generic Types with Primitive Types 44

Not primitive type Cannot Instantiate Generic Types with Primitive Types 44

Not insatiate Cannot Create Instances of Type Parameters 45

Not insatiate Cannot Create Instances of Type Parameters 45

Not static Cannot Declare Static Fields Whose Types are Type Parameters Confusing code: 46

Not static Cannot Declare Static Fields Whose Types are Type Parameters Confusing code: 46

No cast no instaneof Cannot Use Casts or instanceof with Parameterized Types The runtime

No cast no instaneof Cannot Use Casts or instanceof with Parameterized Types The runtime does not keep track of type parameters, so it cannot tell the difference between an Array. List<Integer> and an Array. List<String>. 47

Arrays of Parameterized Types You cannot create arrays of parameterized type 48

Arrays of Parameterized Types You cannot create arrays of parameterized type 48

Generics and Java 7 Older versions: Array. List<String> list = new Array. List<String>(); With

Generics and Java 7 Older versions: Array. List<String> list = new Array. List<String>(); With Java 7: Array. List<String> list = new Array. List<>(); Type information after new are ignored. List<Map<Long, Set<Integer>>> list = new Array. List<>(); 49

end 50

end 50