8 Java Generics and Annotations P 2 Clients

  • Slides: 38
Download presentation
8. Java: Generics and Annotations

8. Java: Generics and Annotations

P 2 — Clients and Servers Generics and Annotations Overview > Generics > The

P 2 — Clients and Servers Generics and Annotations Overview > Generics > The Abstract Factory Pattern > Annotations > Model-Driven Engineering Sources > David Flanagan, Java in a Nutshell, 5 th Edition, O’Reilly. > Go. F, Design Patterns. Elements of Reusable Object-Oriented Software, Addison Wesley, 1997. > Gilad Bracha, Generics in the Java Programming Language, 2004 © O. Nierstrasz 2

P 2 — Clients and Servers What you should know! Why do I need

P 2 — Clients and Servers What you should know! Why do I need generics? How do I use generics? Can I subtype a generic type? When is the Abstract Factory pattern useful? Some uses of Annotations? A Model-Driven Engineering Example © O. Nierstrasz 3

P 2 — Clients and Servers Why do we need Generics? Generics allow you

P 2 — Clients and Servers Why do we need Generics? Generics allow you to abstract over types. The most common examples are container types, the collection hierarchy. © O. Nierstrasz 4

P 2 — Clients and Servers Motivating Example – Old Style List stones =

P 2 — Clients and Servers Motivating Example – Old Style List stones = new Linked. List(); stones. add(new Stone(RED)); stones. add(new Stone(GREEN)); stones. add(new Stone(RED)); Stone first = (Stone) stones. get(0); The cast is annoying but essential! public int count. Stones(Color color) { int tally = 0; Iterator it = stones. iterator(); while (it. has. Next()) { Stone stone = (Stone) it. next(); if (stone. get. Color() == color) tally++; } return tally; } © O. Nierstrasz 5

P 2 — Clients and Servers Motivating Example – New Style using Generics List<Stone>

P 2 — Clients and Servers Motivating Example – New Style using Generics List<Stone> stones = new Linked. List<Stone>(); stones. add(new Stone(RED)); stones. add(new Stone(GREEN)); stones. add(new Stone(RED)); Stone first = /*no cast*/ stones. get(0); List is a generic interface that takes a type as a parameter. public int count. Stones(Color color) { int tally = 0; /*no temporary*/ for (Stone stone : stones) { /*no temporary, no cast*/ if (stone. get. Color() == color) tally++; } return tally; } © O. Nierstrasz 6

P 2 — Clients and Servers Compile Time vs. Runtime Safety List stones =

P 2 — Clients and Servers Compile Time vs. Runtime Safety List stones = new Linked. List(); stones. add(“ceci n’est pas un stone”); Old way . . . Stone stone = (Stone) stones. get(0); New way No check, unsafe List<Stone> stones = new Linked. List<Stone>(); stones. add(“ceci n’est pas un stone”); Runtime error Compile time check . . . Stone stone = stones. get(0); © O. Nierstrasz Runtime is safe 7

P 2 — Clients and Servers Stack Example public interface Stack. Interface { public

P 2 — Clients and Servers Stack Example public interface Stack. Interface { public boolean is. Empty(); public int size(); public void push(Object item); public Object top(); public void pop(); } public interface Stack. Interface<E> { public boolean is. Empty(); public int size(); public void push(E item); public E top(); public void pop(); } © O. Nierstrasz Old way New way: we define a generic interface that takes a type parameter 8

P 2 — Clients and Servers Linked Stack Example public class Link. Stack<E> implements

P 2 — Clients and Servers Linked Stack Example public class Link. Stack<E> implements Stack. Interface<E> { … public class Cell { public E item; public Cell next; public Cell(E item, Cell next) { this. item = item; this. next = next; } } … public E top() { assert !this. Empty(); return _top. item; } © O. Nierstrasz 9

P 2 — Clients and Servers Creating a Stack of Integers Stack<Integer> my. Stack

P 2 — Clients and Servers Creating a Stack of Integers Stack<Integer> my. Stack = new Linked. Stack<Integer>(); my. Stack. push(42); // autoboxing When a generic declaration is invoked, the actual type parameters are substituted for the formal type paramters. © O. Nierstrasz 10

P 2 — Clients and Servers Generics and Subtyping Bar G<Bar> Foo G<Foo> ©

P 2 — Clients and Servers Generics and Subtyping Bar G<Bar> Foo G<Foo> © O. Nierstrasz G is some generic type declaration 11

P 2 — Clients and Servers Generics and Subtyping (II) List<String> ls = new

P 2 — Clients and Servers Generics and Subtyping (II) List<String> ls = new Array<String>(); List<Object> lo = ls; Does this compile? Compile time error as it is not type safe © O. Nierstrasz 12

P 2 — Clients and Servers In other words… Object List<Object> String List<String> ©

P 2 — Clients and Servers In other words… Object List<Object> String List<String> © O. Nierstrasz 13

P 2 — Clients and Servers Wildcards void print. Collection(Collection c) { Iterator i

P 2 — Clients and Servers Wildcards void print. Collection(Collection c) { Iterator i = c. iterator(); for (k=0; k<c. size(); k++){ System. out. println(i. next()); } } void print. Collection(Collection<Object> c) { for (Object e: c){ System. out. println(e); } } © O. Nierstrasz We want a method that prints our all the elements of a collection Here is a naïve attempt at writing it using generics 14

P 2 — Clients and Servers What is the supertype of all kinds of

P 2 — Clients and Servers What is the supertype of all kinds of collections? Collection<? > “collection of unknown” is a collection whose elementtype matches anything - a wildcard type void print. Collection(Collection<? > c) { for (Object e: c){ System. out. println(e); } } © O. Nierstrasz 15

P 2 — Clients and Servers Pitfalls with the Collection of Unknown Collection<? >

P 2 — Clients and Servers Pitfalls with the Collection of Unknown Collection<? > c = new Array. List<String>(); c. add(new Object()); Compile time error Collection<? > c = new Array. List<String>(); … Object my. Object = c. get(); © O. Nierstrasz 16

P 2 — Clients and Servers Bounded Wildcards Consider a simple drawing application to

P 2 — Clients and Servers Bounded Wildcards Consider a simple drawing application to draw shapes (circles, rectangles, …) Shape Canvas draw(Canvas) Circle © O. Nierstrasz Rectangle draw(Shape) draw. All(List<Shape>) Limited to List<Shape> 17

P 2 — Clients and Servers A Method that accepts a List of any

P 2 — Clients and Servers A Method that accepts a List of any kind of Shape… public void draw. All(List<? extends Shape>) {…} a bounded wildcard Shape is the upper bound of the wildcard © O. Nierstrasz 18

P 2 — Clients and Servers More fun with generics import java. util. *;

P 2 — Clients and Servers More fun with generics import java. util. *; … public List<E> sort(Comparator<? super E> comp) { List<E> list = this. as. List(); Collections. sort(list, comp); return list; } public void push. All(Collection<? extends E> collection) { for (E element : collection) { this. push(element); } } © O. Nierstrasz 19

P 2 — Clients and Servers Design Patterns, a preview… “Each pattern describes a

P 2 — Clients and Servers Design Patterns, a preview… “Each pattern describes a problem which occurs over and over again in our environment; and it describes the core of the solution to that problem, in such a way that you can use this solution a million times over…” Christopher Alexander © O. Nierstrasz 20

P 2 — Clients and Servers Creational Patterns … deal with the best way

P 2 — Clients and Servers Creational Patterns … deal with the best way to create objects © O. Nierstrasz 21

P 2 — Clients and Servers Abstract Factory Pattern > A Factory is the

P 2 — Clients and Servers Abstract Factory Pattern > A Factory is the location in the code at which objects are created. > Provides an interface for creating families of related dependent objects. > Let clients create products in any family of products in an abstract way, without having to specify their concrete class. > Separates the details of implementation of a set of objects from its general usage. © O. Nierstrasz 22

P 2 — Clients and Servers Structure of the Abstract Factory Pattern Abstract. Factory

P 2 — Clients and Servers Structure of the Abstract Factory Pattern Abstract. Factory Client create. Product() Abstract. Product Concrete. Factory 1 create. Product() © O. Nierstrasz Concrete. Factory 2 create. Product() concrete. Product 23

P 2 — Clients and Servers Abstract Factory with Generics: Ludo Example package ludo;

P 2 — Clients and Servers Abstract Factory with Generics: Ludo Example package ludo; // NOTE interface for "Abstract Factory" pattern. public interface Factory<T> { public T create. Instance(); } © O. Nierstrasz 24

P 2 — Clients and Servers The Concrete Factory package ludo; public class Ludo.

P 2 — Clients and Servers The Concrete Factory package ludo; public class Ludo. Factory implements Factory<Ludo> { … We specify the type to be Ludo public Ludo create. Instance() { initialize. Home(); initialize. Branchings(); initialize. Main. Ring(quarter. Length); initialize. Home. Runs(quarter. Length); initialize. Nests(); return new Ludo(nest); } … © O. Nierstrasz 25

P 2 — Clients and Servers The Ludo Example <<interface>> Abstract. Factory create. Instance()

P 2 — Clients and Servers The Ludo Example <<interface>> Abstract. Factory create. Instance() : T Ludo. Factory <<interface>> Board add. Player(Player ) … Ludo create. Instance() : Ludo © O. Nierstrasz 26

P 2 — Clients and Servers The Client drives the Ludo Game public class

P 2 — Clients and Servers The Client drives the Ludo Game public class Driver implements Runnable { private Board board; public Driver(Factory<? extends Board> factory) { this. board = factory. create. Instance(); board. add. Player(new Player()); } … The Driver can drive any Board game Specify which Game Factory we want public class Main { public static void main(String[] args) { Runnable game. Driver = new Driver(new Ludo. Factory()); game. Driver. run(); } © O. Nierstrasz 27

P 2 — Clients and Servers Annotations > Annotations are a special kind of

P 2 — Clients and Servers Annotations > Annotations are a special kind of comments. > Annotations are meta-describtions. > Same as comments, annotations do not change or affect the semantics of the program, ie the runtime behavior. > Different than comments, annotations can be accessed and used by third-party tools (eg JUnit) or even your program itself. © O. Nierstrasz 28

P 2 — Clients and Servers For example JUnit uses annotations @Before public void

P 2 — Clients and Servers For example JUnit uses annotations @Before public void setup() { … @Test public void some. Test() { … @Test(expected=IOException. class) public void another. Test() { … JUnit uses annotations to find out which methods are test methods, and which are part of the setup. You may even pass parameters to the annotations. © O. Nierstrasz 29

P 2 — Clients and Servers Example: a model-driven UI > We want UI

P 2 — Clients and Servers Example: a model-driven UI > We want UI to edit any kind of object with any kind of properties (ie Model-driven Engineering) > The example requieres these steps > Define custom annotations for getters and setters. > Annotate our classes with these annotations > Write a UI class that access these annotations at runtime to create a custom UI. © O. Nierstrasz 30

P 2 — Clients and Servers Model-driven Engineering : Book title: String author: String

P 2 — Clients and Servers Model-driven Engineering : Book title: String author: String … Model can be any kind of object with any kind of properties © O. Nierstrasz model-driven Model-driven UI labels and field are automatically created based on the model 31

P 2 — Clients and Servers Defining our custom annotations import java. lang. annotation.

P 2 — Clients and Servers Defining our custom annotations import java. lang. annotation. *; @Retention(Retention. Policy. RUNTIME) @Target(Element. Type. METHOD) public @interface Get. Property { public String value(); } This defines a @Get. Property annotation for methods. The annotation is accessible during runtime. © O. Nierstrasz 32

P 2 — Clients and Servers Annotating our domain classes @Get. Property(“Titel”) public void

P 2 — Clients and Servers Annotating our domain classes @Get. Property(“Titel”) public void get. Titel() { return title; } @Get. Property(“Autor”) public void get. Author() { return author; } … © O. Nierstrasz 33

P 2 — Clients and Servers Use reflection to access the annotations of any

P 2 — Clients and Servers Use reflection to access the annotations of any object import java. reflect. Method; public void print. Annotated. Methods(Object obj) { for (Method m : obj. get. Class(). get. Methods()) { if (m. is. Annotation. Present(Get. Property. class)) { this. process. Property(obj, m); } } } The for loop iterates over all methods of obj’s Class. The if block is only entered for annotated methods. © O. Nierstrasz 34

P 2 — Clients and Servers Use reflection to call any method on any

P 2 — Clients and Servers Use reflection to call any method on any object import java. reflect. Method; public void proccess. Property(Object obj, Method m) throws Exception { Get. Property g = m. get. Annotation(Get. Property. class); this. add(new Jlabel(g. value())); String value = (String) m. invoke(obj); this. add(new JText. Field(value)); } We use reflection to invoke the method m on the object obj. © O. Nierstrasz 35

P 2 — Clients and Servers What you should know! Why do I need

P 2 — Clients and Servers What you should know! Why do I need generics? Why is casting dangerous? How do I use generics? Can I subtype a generic type? When is the Abstract Factory pattern useful? Some uses of Annotations? A Model-Driven Engineering Example © O. Nierstrasz 36

P 2 — Clients and Servers Can you answer these questions? Why is List<Object>

P 2 — Clients and Servers Can you answer these questions? Why is List<Object> not the supertype of List<String>? Which pattern could we use to implement a Windowing Toolkit that supports multiple “look-and-feel” user interfaces? What are the advantages and disadvantages of using the Abstract Factory Pattern? © O. Nierstrasz 37

P 2 — Clients and Servers License > http: //creativecommons. org/licenses/by-sa/2. 5/ Attribution-Share. Alike

P 2 — Clients and Servers License > http: //creativecommons. org/licenses/by-sa/2. 5/ Attribution-Share. Alike 2. 5 You are free: • to copy, distribute, display, and perform the work • to make derivative works • to make commercial use of the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor. Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. • For any reuse or distribution, you must make clear to others the license terms of this work. • Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. © O. Nierstrasz 38