copyright © 2003 langr software solutions. all rights reserved. unleashing the tiger generics and...
TRANSCRIPT
Copyright © 2003 Langr Software Solutions. All rights reserved.
Unleashing the TigerGenerics and Fun Stuff in J2SE 1.5
Jeff LangrLangr Software Solutions
http://www.LangrSoft.comDecember 2003
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
Tiger, Tiger Burning BrightLike a geek who works all nightWhat new-fangled bit or byteCould ease the hacker's weary plight?
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
What?
Java community process (JCP) JSR's (Java Specification Requests) 14, 201,
175 Six areas of improvement
Generics Enhanced for loop (foreach) Autoboxing; varargs Typesafe enums Static import Metadata
“Syntactic sugar”
Copyright © 2003 Langr Software Solutions. All rights reserved.
Other Interesting Items
StringBuilder—unsynchronized StringBuffer Both extend AbstractStringBuilder
Two new look & feels: XP, Linux GTK 2.0 New API java.util.concurrent Updated XML support javac -Xlint warnings
all, deprecation, unchecked, switchcheck, path, serial, finally
Prefix with – to turn off System.nanoTime()
No ties to system clock
Copyright © 2003 Langr Software Solutions. All rights reserved.
Why?
Make programs: Clearer Safer Shorter Easier to develop ... without sacrificing compatibility
Language supp't for common idioms Avoid boilerplate code
Compete with C#
Copyright © 2003 Langr Software Solutions. All rights reserved.
What not?
Operator overloading Delegates Call by reference
out / ref in C# const Default values on parms
Copyright © 2003 Langr Software Solutions. All rights reserved.
How?
Minimal byte code/VM changes Most changes to compiler and class library
Collection classes retrofitted Still support legacy use
Only new keyword is enum New keywords avoided Preserves compatibility
Doesn't break code using keyword as identifier
Copyright © 2003 Langr Software Solutions. All rights reserved.
How do I?
Early access support from java.sun.com “Adding Generics to the Java Programming
Language” Current version 2.2; July 23 Comes with a batch file = easiest Ant support
Little IDE support yet CodeGuide – cost NetBeans can be configured to use it IDEA: generics support; free early access
version jEdit (plugin) DrJava (drjava.org)
Copyright © 2003 Langr Software Solutions. All rights reserved.
When?
Next pre-release drop “Real Soon Now” Full customer ship initially slated for EOY
2003 Now probably August 2004
Betas in 1Q, 2Q 2004
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
To the most despised castWe'll bid a fond farewell at lastWith generics' burning spearThe need for cast will disappear
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
Using Generics
aka parameterized types Provide type-safe collections
Eliminates casting Collection example:
List<String> names = new ArrayList<String>();names.add("abc");names.add("def");String firstName = names.get(0);
// names.add(new Date()); // compile error: cannot find symbol
Copyright © 2003 Langr Software Solutions. All rights reserved.
Using Generics: Map
Map example:
Date today = new Date();Date tomorrow = new Date(today.getTime() + 86400 * 1000);
Map<String,Date> events = new HashMap<String, Date>();events.put("today", today);events.put("tomorrow", tomorrow);
today = events.get("today");tomorrow = events.get("tomorrow");
Copyright © 2003 Langr Software Solutions. All rights reserved.
Using Generics...
Comparable example:
class Employee implements Comparable<Employee> { String id; Employee(String id) { this.id = id; } public int compareTo(Employee that) { return this.id.compareTo(that.id); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
While Iterators have their usesThey sometimes strangle us like noosesWith enhanced-for's deadly rayIterator's kept at bay
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
for-each
Replaces standard iteration idiom:Iterator it = names.iterator();while (it.hasNext()) { String string = (String)it.next(); System.out.println(string.toUpperCase());} ...with:for (String string: names) System.out.println(string.toUpperCase());
names must be bound to String i.e. List<String> names
Copyright © 2003 Langr Software Solutions. All rights reserved.
for-each
Also works with arrays
String[] names = { "a", "b", "c" };for (String name: names) System.out.println(name.toUpperCase());
Copyright © 2003 Langr Software Solutions. All rights reserved.
Making Your Class Iterable
java.lang now contains the Iterable interfaceclass Department implements Iterable<Employee> { private List<Employee> employees = new ArrayList<Employee>(); public Iterator<Employee> iterator() { return employees.iterator(); } public void hire(Employee employee) { employees.add(employee); }} You can now use for-each (next page)
Copyright © 2003 Langr Software Solutions. All rights reserved.
Using an Iterable Class
Can use for-each to iterate all emps in dept:Department dept = new Department();dept.hire(new Employee("1"));dept.hire(new Employee("2"));for (Employee emp: dept) System.out.println(emp);
Doesn't work in public pre-release compiler ...Yet. Works in limited availability beta. You must cast the collection being iterated:
for (Employee emp: (Iterable<Employee>)dept)
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
When from collections ints are drawnWrapper classes make us mournWhen Tiger comes, we'll shed no tearsWe'll autobox them in the ears
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
Autoboxing
Currently:List grades = new ArrayList();grades.add(new Integer(10));int grade = ((Integer)grades.get(0)).intValue();System.out.println("" + grade);
With autoboxing:List<Integer> grades = new ArrayList<Integer>();grades.add(10);int grade = grades.get(0);System.out.println(grade);
Copyright © 2003 Langr Software Solutions. All rights reserved.
Autoboxing Notes
Autounboxing not working in 2.2 drop Must do:
int grade = grades.get(0).intValue(); Autoboxing only on parms. Can't do:10.toString(); // not yet? Ever? Autoboxing creates new wrapper objects
Expensive for large volume Autounboxing null from a map
Throws NullPointerException, on assignment only
Collections.getWithDefault() ? (not yet)
Copyright © 2003 Langr Software Solutions. All rights reserved.
Varargs
Variable-length argument listsDepartment dept = new Department();dept.hire( new Employee("1"), new Employee("2"), new Employee("3"));dept.hire(new Employee("4"));
// code in Department:public void hire(Employee... hires) { for (Employee employee: hires) employees.add(employee);}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
The int-enum will soon be gonelike a foe we've known too longWith typesafe-enum's mighty powerOur foe will bother us no more
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
Typesafe enum
Uses Bloch's Typesafe Enum pattern An enum declares a new, serializable type,
with named instances:enum Grade { A, B, C, D, F }; The Student class:class Student { List<Grade> grades = new ArrayList<Grade>(); void add(Grade g) { grades.add(g); } Grade getGrade(int i) { return grades.get(i); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Using enum
Referred to like a static variableStudent student = new Student();student.add(Grade.A); May be used in switch statementsswitch (student.getGrade(0)) { case Grade.A: print("great"); break; case Grade.B: print("good"); break; case Grade.C: print("ok"); break; case Grade.D: print("eh"); break; case Grade.F: print("loser"); break;} Can't extend enums (keeps them safe)
Copyright © 2003 Langr Software Solutions. All rights reserved.
Enhancing enum
May have fields, constructors, methodsenum Grade { A(4), B(3), C(2), D(1), F(0); private int points; public Grade(int p) { points = p; } public int points() { return points; }}class Student { // ... double getGPA() { double total = 0.0d; for (Grade grade: grades) total += grade.points(); return total / grades.size(); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Polymorphic enums
Enum constants allow method declarationsabstract enum StudentType { REGULAR { double getGPA(List<Grade> grades) { double total = 0.0d; for (Grade grade: grades) total += grade.getGradePoints(); return total / grades.size(); } }, SENATORS_SON { double getGPA(List<Grade> grades) { return 4.0d; } }; abstract double getGPA(List<Grade> grades);}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Additional enum Fields
Get the collection of enum valuesfor (Grade grade: Grade.VALUES) System.out.println(grade); Construct by nameGrade grade = Grade.valueOf("F"); Obtain ordinal, nameenum Grade { // ... public String toString() { return "(" + ordinal + ") " + name + "; points = " + points; }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
And from the constant interfacewe shall inherit no disgraceWith static import at our side, our joy will be unqualified
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
Static Import
Eliminate bad “Constant Interface” pattern Interfaces should be used to define types Poor design; exposes impl details to clients Locks class to always import constant interface
Imports all static methods of a class Currently:public double hypotenuse(double a, double b) { return Math.sqrt( Math.pow(a, 2.0) + Math.pow(b, 2.0));}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Static Import
Now:import static java.lang.Math.*;class Test { public double hypotenuse(double a, double b){
return sqrt(pow(a, 2.0) + pow(b, 2.0)); }} Single fields/static methods can also be
imported:import static java.lang.Math.PI;
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
And as for noble metadataI'll have to sing its praises laterIts uses are so numerousTo give their due, I'd miss the bus
-Joshua Bloch
Copyright © 2003 Langr Software Solutions. All rights reserved.
Metadata (Speculative)JSR 175
Annotated code to help support tools Similar to C# attributes Example use in C#: NUnit
Will probably use @ “annotation-type”-> a-t -> @ ;-)
Example: mark a method so web services tool can autogen IF
public class CoffeeOrder { @Remote public Coffee [] getPriceList() { ... }} Will allow you to create your own @ tags
Copyright © 2003 Langr Software Solutions. All rights reserved.
Generics Revisited
Test:public void testFirst() { NumList<Integer> nums = new NumList<Integer>(); nums.add(5); nums.add(25); nums.add(125); assertEquals(5, nums.getFirst());} NumList<Integer> is a parameterized type
Copyright © 2003 Langr Software Solutions. All rights reserved.
Type Parameters
<T1,T2> is a type parameter list T is a naked type parameterimport java.util.*;class NumList<T> { private List<T> numbers = new ArrayList<T>(); public void add(T number) { numbers.add(number); } public T getFirst() { return numbers.get(0); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Constrained Generics
Allow only numerics: use a boundclass NumList<T extends Number> { Allows this (in NumList):public double total() { double total = 0.0d; for (T number: numbers) total += number.doubleValue(); return total;} Disallows this (in client):NumList<Date> dateNums = new NumList<Date>(); Default bound is java.lang.Object
Copyright © 2003 Langr Software Solutions. All rights reserved.
Wildcards
Allows substituting any type Can have boundspublic void addAll(NumList<? extends T> src) { for (T number: src.numbers) numbers.add(number);}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Generic Methods, Super
Parameter section precedes return typestatic <T extends Number> void add(T element, NumList<? super T> list) { list.add(element);} element can be added to a NumList bound
to a supertype of T
Copyright © 2003 Langr Software Solutions. All rights reserved.
Additional Bounds (&)
Specify additional interface bounds w/ & Can be used to enforce parameter types<T extends SimpleList&Summable> T min(T first, T second) { return avg(first) < avg(second) ? first : second;}<T extends SimpleList&Summable> double avg(T list) { return list.total() / list.size();} Perhaps useful when you can't change the
parameterized type
Copyright © 2003 Langr Software Solutions. All rights reserved.
Implementation: Erasure
List<T> is erased to List Naked type parm T erased to its upper
bounds Object by default
Run javac -s to see generated code Send output (.java) to a different directory The pre-release doesn't protect you from
overwriting source!
Copyright © 2003 Langr Software Solutions. All rights reserved.
Limitations
Can't use primitives for type parms But there's autoboxing
Can't use naked type parms in: statics, casts, instanceof, new,
implements/extends Can't use type variables in catch clauses Arrays of generic types not allowed
Except List<?>[]
Copyright © 2003 Langr Software Solutions. All rights reserved.
Raw Types
Legacy use of parameterized types is OKNumList g = new NumList();g.add("s"); // will not compile
Resolves to upper bounds Generates unchecked warnings. For details:
-warnunchecked (pre); -Xlint:unchecked (beta) Use casts to (evilly) circumvent type checksList<String> e = new ArrayList<String>();((List)e).add(3);
Evil begets evil:String e0 = e.get(0);
...generates a ClassCastException
Copyright © 2003 Langr Software Solutions. All rights reserved.
More Topics (briefly)...
Overloading rules Class can't have two methods w/ same name
and erasure Bridge methods Covariant return types Reflections
Copyright © 2003 Langr Software Solutions. All rights reserved.
Bridge Methods
Maybe necessary in override situations:class Emp<T> { abstract T id(T x); }class USEmp extends Emp<String> { String id(String x) { return x; } } Generates:class Emp { abstract Object id(Object x); }class USEmp extends Emp { String id(String x) { return x; } Object id(Object x) { return id((String)x); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Multiple Return Types!
class Bucket<T> { abstract T next(); }class LeakyBucket extends Bucket<String> { String next() { return ""; } } Generates:class Bucket { abstract Object next(); }class USEmp extends Emp { String next() { return ""; }/*synthetic*/Object next() { return this.next(); }
} Would be compile error if original source Bytecodes generated are ok
Since methods use full sig at bytecode level
Copyright © 2003 Langr Software Solutions. All rights reserved.
Covariant Return Types
Return type varies in same direction as containing type
class Bag { Bag copy() { return this; } }class LeakyBag extends Bag { LeakyBag copy() { return this; }} Generates:class Bag { Bag copy() { return this; } }class LeakyBag extends Bag { LeakyBag copy() { return this; }/*synthetic*/ Bag copy() { return this.copy(); }}
Copyright © 2003 Langr Software Solutions. All rights reserved.
Reflections
class Class<T> { T newInstance(); public Constructor<T> getConstructor(Class<?>... parmTypes); public Constructor<T> getDeclaredConstructor(Class... parameterTypes);
class Constructor<T> {public T newInstance()public Class<T> getDeclaringClass();public T newInstance(Object... initargs);
X.class has type Class<X> For expression e of static type X
e.getClass() is of type Class<X> Example use: declaring truly typesafe wrapper
Copyright © 2003 Langr Software Solutions. All rights reserved.
Take Care...
Previous limitations and rules suggest how complex generics can be
If you're unsure... Good: Read the spec Better: Try it—write a test! Best: Avoid it
If you're having a tough time coding it... Others will have a tough time maintaining it
Copyright © 2003 Langr Software Solutions. All rights reserved.
Tiger
Oh Tiger of sugar, oh Tiger of fluff,Many nice features to call C#'s bluff,My only warning for this endeavor:Just make sure you aren't too clever!
-Jeff Langr