copyright © 2003 langr software solutions. all rights reserved. unleashing the tiger generics and...

Post on 26-Mar-2015

213 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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

top related