Java Generics

  • 1,713 views
Uploaded on

Simple introduction to the basics of Java 1.5 generics

Simple introduction to the basics of Java 1.5 generics

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,713
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
58
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • GOOD AFTERNOON MY NAME IS … BEFORE WE START … ANYONE WITH C++ KNOWLEDGE? ANYONE THINK TYPED LANGUAGES ARE GOOD?
  • WHY CHANGE? I’M PRODUCTIVE AND COMFORTABLE AS IS.
  • WE’RE GOING TO MAKE A SIMPLE CLASS TO ILLUSTRATE SOME OF THE POWER AND NOTATION OF GENERICS.
  • WE START WITH A PRE-JAVA 5 VERSION. WE’LL USE JAVA 1.4 NOTE THAT OUR EXAMPLE LACKS JAVADOC COMMENTS. DON’T DO THIS IN ANY OF YOUR OWN CODE!
  • OUR CODE IS SOMEWHAT TYPE AMBIGUOUS, ESPECIALLY FOR THE COLLECTIONS
  • WE’LL REWIRTE OUR EXAMPLE FOR JAVA 5 USING THE GENERICS BUILT INTO THE REVISED JAVA.UTIL.* PACKAGES
  • OKAY, WE GOT RID OF THE TYPE AMBIGUITY IN THE COLLECTIONS. BUT WE NEED TO REWRITE THIS FOR EVERY NEW KIND OF STACK WE NEED! C++ SOLUTION IS TEMPLATES. JAVA SOLUTION IS GENERICS AGAIN.
  • NOTE COMPILER WOULD IMMEDIATELY CATCH THE “int” WE OVERLOOKED IN OUR PRIOR IMPLEMENTATION (AND AUTO-UNBOX IT)
  • THAT SECOND PIECE OF BAD NEWS IS REALLY BAD. WATCH WHAT HAPPENS WHEN WE CONVERT A SIMPLE “PRINT ALL ELEMENTS IN A COLLECTION” TO USE GENERICS
  • WHAT IF WE DON’T WANT THE ULTIMATE BASE TYPE (Object)? WHAT IF WE NEED SOME HIGHER TYPE? AN UPPER BOUND AS WE CLIMB THE HIERARCHY OF OBJECT INHERITANCE, SO TO SPEAK?
  • WHAT IF WE DON’T WANT THE ULTIMATE BASE TYPE (Object)? WHAT IF WE NEED SOME HIGHER TYPE? AN UPPER BOUND AS WE CLIMB THE HIERARCHY OF OBJECT INHERITANCE, SO TO SPEAK?
  • WHAT IF WE DON’T WANT THE ULTIMATE BASE TYPE (Object)? WHAT IF WE NEED SOME HIGHER TYPE? AN UPPER BOUND AS WE CLIMB THE HIERARCHY OF OBJECT INHERITANCE, SO TO SPEAK?
  • THIS WAS JUST AN INTRODUCTION. THERE ARE SOME VERY USEFUL TOPICS WE HAVE NOT EVEN TOUCHED ON.

Transcript

  • 1. Generics in Java 5 Better Code in Fewer Keystrokes Jeslie Chermak ( [email_address] )
  • 2. What is a “generic”?
    • Generics — An enhancement to the type system that supports operations on objects of various types while providing compile-time type safety. Note that this lesson is for advanced users. Refer to http ://java.sun.com/docs/books/ tutorial
    • This talk is based on information from http ://java.sun.com/docs/books/tutorial/extra/ generics
  • 3. Why Should I Use It?
    • COMPILE-TIME TYPE CHECKING!
      • Compiler enforces type correctness.
      • Compiler as debugger!
    • Faster runtime execution.
    • Less code to enter, so fewer chances for programmer error.
    • More readable code, so easier to understand later.
  • 4. Simple Class
    • Create a new class in package com.jcc.training.generics
    • Class will implement a traditional “stack” containing Integer s
    • Only methods are push , pop , top
    • Allow NULL s in stack
  • 5. Java 1.4 Implementation
    • package com.jcc.training.generics;
    • import java.util.ArrayList;
    • import java.util.List;
    • public class Stack {
    • private final List stack = new ArrayList();
    • public void push( final Integer value) {
    • this . stack .add(value); // NULL allowed!
    • }
    • public Integer top() {
    • if ( this . stack .isEmpty()) throw new IllegalStateException();
    • return (Integer) this . stack .get( this . stack .size() - 1);
    • }
    • public Integer pop() {
    • final Integer value = this .top();
    • this . stack .remove( this . stack .size() - 1);
    • return value;
    • }
    • }
  • 6. WIBNIF
    • Problem: Collection objects always use Object as base type
    • Solution: introduce type parameter
  • 7. Java 5 Implementation
    • package com.jcc.training.generics;
    • import java.util.ArrayList;
    • import java.util.List;
    • public class Stack {
    • private final List<Integer> stack = new ArrayList<Integer>(); // field typed!
    • public void push( final Integer value) {
    • this . stack .add(value); // NULL allowed!
    • }
    • public Integer top() {
    • if ( this . stack .isEmpty()) throw new IllegalStateException();
    • return this . stack .get( this . stack .size() - 1); // no cast!
    • }
    • public Integer pop() {
    • final int value = this .top(); // OOPS!
    • this . stack .remove( this . stack .size() - 1);
    • return value;
    • }
    • }
  • 8. WIBNIF
    • Problem: class es need to be rebuilt for differing base types
    • Solution: introduce formal type parameter and parameterized type (think parameters to a method, but applied at the class level)
  • 9. Improved Implementation
    • package com.jcc.training.generics;
    • import java.util.ArrayList;
    • import java.util.List;
    • public class Stack<E> { // class typed!
    • private final List<E> stack = new ArrayList<E>(); // typed by class
    • public void push( final E value) { // typed by class
    • this . stack .add(value); // NULL allowed!
    • }
    • public E top() { // typed by class
    • if ( this . stack .isEmpty()) throw new IllegalStateException();
    • return this . stack .get( this . stack .size() - 1);
    • }
    • public E pop() { // typed by class
    • final E value = this .top(); // typed by class
    • this . stack .remove( this . stack .size() - 1);
    • return value;
    • }
    • }
  • 10. Good News
    • Each instance of a generic class shares the same code (unlike C++ template)
    • Feeds upon itself: generic type parameters can propagate (e.g. List<E> within Stack<E> )
    • Stack<E> x = new Stack<E>();
  • 11. Bad News
    • Each instance of a generic class shares the same code!
      • static s can’t access generic type information
    • List<String> ls = new List<Object>();
    • List<Object> ls = new List<String>();
    • … Erasures …
  • 12. Wildcard types
    • Old style:
    • public void printCol( Collection c) {
    • Iterator i = c.iterator();
    • for (i.hasNext()) {
    • System . out .println(i.next());
    • }
    • }
    • Can’t do:
    • public void printCol( Collection<Object> c) {
    • for ( Object o : c) {
    • System . out .println(o);
    • }
    • }
    • So use ? as the wildcard (supertype):
    • public void printCol( Collection<?> c) {
    • for ( Object o : c) {
    • System . out .println(o);
    • }
    • }
  • 13. Bounded Wildcard types
    • What about when you want a base type other than Object ?
    • public abstract class Shape {
    • public abstract void draw(Canvas c);
    • }
    • public class Rectangle extends Shape { … }
    • public class Circle extends Shape { … }
    • Can’t do (in class Canvas ):
    • public void drawAll(List<Shape> shapes) {
    • for ( Shape s : shapes ) s.draw( this );
    • }
    • So use ? extends as the bounded wildcard:
    • public void drawAll(List<? extends Shape> shapes) {
    • for ( Shape s : shapes ) s.draw( this );
    • }
  • 14. Generic methods
    • Parameterize types based on arguments
    • static <T> void fromArrayToCollection(T[] a, Collection<T> c) {
    • for (T o : a) {
    • c.add(o); // Correct
    • }
    • }
    • Now have compiler infer type of T :
    • Object[] oa = new Object[100];
    • Collection<Object> co = new ArrayList<Object>();
    • fromArrayToCollection(oa, co); // T inferred to be Object
    • String[] sa = new String[100];
    • Collection<String> cs = new ArrayList<String>();
    • fromArrayToCollection(sa, cs); // T inferred to be String
    • fromArrayToCollection(sa, co); // T inferred to be Object
  • 15. Erasures
    • Generic code like this …
    • public String loophole(Integer x) {
    • List<String> ys = new LinkedList<String>();
    • List xs = ys;
    • xs.add(x); // Compile-time unchecked warning
    • return ys.iterator().next();
    • }
    • Actually behaves as …
    • public String loophole(Integer x) {
    • List ys = new LinkedList;
    • List xs = ys;
    • xs.add(x);
    • return (String) ys.iterator().next(); // run time error
    • }
    • Generics are implemented by the Java compiler as a front-end conversion called erasure !
  • 16. Some minor details …
    • Working with pre-Java 5.0 code: http://download-llnw.oracle.com/javase/tutorial/extra/generics/legacy.html
    • Lower bounds and multiple bounds: http://download-llnw.oracle.com/javase/tutorial/extra/generics/morefun.html
    • Wildcard capture: http://download-llnw.oracle.com/javase/tutorial/extra/generics/morefun.html
    • Class literals as runtime types: http://download-llnw.oracle.com/javase/tutorial/extra/generics/literals.html
    • Legacy code upgrade issues: http://download-llnw.oracle.com/javase/tutorial/extra/generics/convert.html