JDK 1.5 and modern patterns Peter Antman, CTO, 2007 Mogul
Whats on in the Java space? A refresher on JDK 1.5 Although old – not yet fully utilized
The base to using J2EE effectively
New Language Feature, new libraries, new methods, new runtime Some important new patterns POJO
Interceptors
Dependency Injection/IoC
AOP
New features in JDK 1.5 Generics
New for loop
Autoboxing
Varargs
Enums
Static import
Annotations
New concurrency libraries
New stuff in java.lang.System, java.util.*
New management API and tools (JMX)
Better runtime (gc)
And more...
Generics – stronger typing Generics: a new language feature that makes Java more strongly typed
Makes it possible to write classes that handles any type logically, but bind it to a specific type when programming public interface List<E> extends Collection <E> {} <E>  - whats that?
A type parameter
Generics is parameterized classes (and methods)
Much like you may create new class instances with different values at runtime  ToBe notToBe = new ToBe(false); You can create a specialized typed instance programmatically List<String> myStrings = new List<String>();
Generics and Collections Most widely used with Collections
No more typecasts
Only use arrays for performance critical work
Cleaner code for simple cases
Generics –  compile time check Old runtime checked code List strings = new ArrayList(); strings.add(new Integer(1));// Ok String s = (String)strings.get(0);//   Runtime error New safe code List<String> strings = new ArrayList<String>(); strings.add(new Integer(1));//  Compile error String s = strings.get(0);//  No typecast
Generics - map Iterating a Map of Maps – non generic Iterator it = topMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry e =  (Map.Entry) it.next(); Iterator itSub = ( (Map) e.getValue()).entrySet().iterator(); while(itSub.hasNext()) { Map.Entry eSub =  (Map.Entry) itSub.next(); String k =  (String) eSub.getKey(); } } Iterating a Map of Maps – generic Iterator <Map.Entry<String,  Map<String, String>>>  it = topMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry <String,  Map<String, String>>  e = it.next(); Iterator <<Entry.Set<String, String>>  itSub = e.getValue().entrySet().iterator(); while(itSub.hasNext()) { Map.Entry <String, String>  eSub = itSub.next(); String k = eSub.getKey(); } }
Generics – erasure Generics works by erasure
The generic type informations is lost in byte code
Source code/Byte code roundtripping not possible List<String> strings = new ArrayList<String>(); strings.add(&quot;hello&quot;); String h = strings.get(0); Becomes ArrayList arraylist = new ArrayList(); arraylist.add(&quot;hello&quot;); String s = (String)arraylist.get(0);
Generics – defining a class Creating a generic interface interface Factory<P> { P create(); } Creating a generic class static class FactoryImpl<T> implements Factory<T> { FactoryImpl(Class<T> c) {...}; public T create() {...} } Factory<My> f1 = new FactoryImpl<My>(My.class); My m1 = f.create();
Generic methods Possible to make methods generic
Done by prepending a type parameter
Lets redo javax.rmi.PortableRemoteObject public class PortableRemoteObject { static  <T>  T narrow(Object o, Class<T> t) {...} } The type is inferred during call My m2 = narrow(new My(), My.class); When inferred type is not clear one may have to help, calling static <T> List<T> trouble(T t1, T t2) like this: List<Object> lo1 = GenericsTest. <Object> trouble(new Integer(1), &quot;hello&quot;); //Must be a “.” before!
Generics – inheritance Inheritance is a little bit surprising
Parameterizing a class with “compatible” types does not make the classes type compatible List<Integer> does  NOT  inherit List<Number> runtime typing system not the same as compile time List<Number> ln = new ArrayList<Number>(); List<Integer> li = new ArrayList<Integer>(); ln.getClass().isInstance(li);// TRUE! instanceof does not work with generics because of erasure li instanceof List<Number> is not valid
Generics – inheritance example List<Number> ln = new List<Number>();
Can put both Integer and Double
ln.add(new Double(3.14));
List<Integer> li = new List<Integer>();
May only take Integer and subclasses, not Double
ln = new List<Integer>(); //  Compile error
Not OK, Integer can not risk being a Double
Generics – get principle Inheritance of generics classes is done with the extends and super wildcards
To be able to read from an inheritable generic class one must use the extends wildcard
<? extends T>  says that we can use any instance of the generic class that has been instantiated with the typ T or any subtypes of T class Reader<S> { S read(Reader<? extends S> r) { return r.read(); } Without this  Reader<My>  would only be able to read other  Reader<My>  instances. With extends it may also read for example  Reader<MySub>
Generics – put principle To be able to put stuff into a “inherited” generic type one has to use the super  wildcard
<? super T>  say that any type that is a parent to T used to parameterized a generic class will make that class a subtype of the declaring class
Look at  List<? super Number> . What is List<Object>?
Since Object is a supertype of Number List<Object> is a subtype of List<? super Number>!
When writing the limiting factor is the type to write (the thing you write into must be same type or a parent) static class Writer<D> { void write(Writer<? super D> w)  { w.write(); } Without this  Writer<My2>  would not be able to write to a  Writer<My>
Generic – more complicated stuff Wildcard capture
Wildcard not allowed at top level during instance creation
Bounded type variables
Multiple bounds
Unbounded generics
Arrays and generics
Exceptions
New rule when overriding Old rule: a subclass can only override a method if it has the exact same signature
To override  public Object clone()  one had to do it like this class Person { public Object clone() {} } Person pc =  (Person) person.clone(); New rule: the return type may be a subtype of the type returned by the overridden method. Its now legal to do this: class Person { public  Person  clone() {} } Person pc = person.clone();
Autoboxing Java typesystem primitives which are NOT objects: int, byte, boolean...
Objects inheriting from java.lang.Object
Primitives have no common parent
Autoboxing - primitives Primitives does not work well with Collections or any other class that work on  Object void visit(String page) { int val = 0; if (stats.containsKey(page)) { val =  ((Integer) stats.get(page)).intValue(); } Integer newVal = new Integer(++val) ; stats. put (page, newVal); }

Java 1.5 - whats new and modern patterns (2007)

  • 1.
    JDK 1.5 andmodern patterns Peter Antman, CTO, 2007 Mogul
  • 2.
    Whats on inthe Java space? A refresher on JDK 1.5 Although old – not yet fully utilized
  • 3.
    The base tousing J2EE effectively
  • 4.
    New Language Feature,new libraries, new methods, new runtime Some important new patterns POJO
  • 5.
  • 6.
  • 7.
  • 8.
    New features inJDK 1.5 Generics
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
    New stuff injava.lang.System, java.util.*
  • 17.
    New management APIand tools (JMX)
  • 18.
  • 19.
  • 20.
    Generics – strongertyping Generics: a new language feature that makes Java more strongly typed
  • 21.
    Makes it possibleto write classes that handles any type logically, but bind it to a specific type when programming public interface List<E> extends Collection <E> {} <E> - whats that?
  • 22.
  • 23.
    Generics is parameterizedclasses (and methods)
  • 24.
    Much like youmay create new class instances with different values at runtime ToBe notToBe = new ToBe(false); You can create a specialized typed instance programmatically List<String> myStrings = new List<String>();
  • 25.
    Generics and CollectionsMost widely used with Collections
  • 26.
  • 27.
    Only use arraysfor performance critical work
  • 28.
    Cleaner code forsimple cases
  • 29.
    Generics – compile time check Old runtime checked code List strings = new ArrayList(); strings.add(new Integer(1));// Ok String s = (String)strings.get(0);// Runtime error New safe code List<String> strings = new ArrayList<String>(); strings.add(new Integer(1));// Compile error String s = strings.get(0);// No typecast
  • 30.
    Generics - mapIterating a Map of Maps – non generic Iterator it = topMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry e = (Map.Entry) it.next(); Iterator itSub = ( (Map) e.getValue()).entrySet().iterator(); while(itSub.hasNext()) { Map.Entry eSub = (Map.Entry) itSub.next(); String k = (String) eSub.getKey(); } } Iterating a Map of Maps – generic Iterator <Map.Entry<String, Map<String, String>>> it = topMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry <String, Map<String, String>> e = it.next(); Iterator <<Entry.Set<String, String>> itSub = e.getValue().entrySet().iterator(); while(itSub.hasNext()) { Map.Entry <String, String> eSub = itSub.next(); String k = eSub.getKey(); } }
  • 31.
    Generics – erasureGenerics works by erasure
  • 32.
    The generic typeinformations is lost in byte code
  • 33.
    Source code/Byte coderoundtripping not possible List<String> strings = new ArrayList<String>(); strings.add(&quot;hello&quot;); String h = strings.get(0); Becomes ArrayList arraylist = new ArrayList(); arraylist.add(&quot;hello&quot;); String s = (String)arraylist.get(0);
  • 34.
    Generics – defininga class Creating a generic interface interface Factory<P> { P create(); } Creating a generic class static class FactoryImpl<T> implements Factory<T> { FactoryImpl(Class<T> c) {...}; public T create() {...} } Factory<My> f1 = new FactoryImpl<My>(My.class); My m1 = f.create();
  • 35.
    Generic methods Possibleto make methods generic
  • 36.
    Done by prependinga type parameter
  • 37.
    Lets redo javax.rmi.PortableRemoteObjectpublic class PortableRemoteObject { static <T> T narrow(Object o, Class<T> t) {...} } The type is inferred during call My m2 = narrow(new My(), My.class); When inferred type is not clear one may have to help, calling static <T> List<T> trouble(T t1, T t2) like this: List<Object> lo1 = GenericsTest. <Object> trouble(new Integer(1), &quot;hello&quot;); //Must be a “.” before!
  • 38.
    Generics – inheritanceInheritance is a little bit surprising
  • 39.
    Parameterizing a classwith “compatible” types does not make the classes type compatible List<Integer> does NOT inherit List<Number> runtime typing system not the same as compile time List<Number> ln = new ArrayList<Number>(); List<Integer> li = new ArrayList<Integer>(); ln.getClass().isInstance(li);// TRUE! instanceof does not work with generics because of erasure li instanceof List<Number> is not valid
  • 40.
    Generics – inheritanceexample List<Number> ln = new List<Number>();
  • 41.
    Can put bothInteger and Double
  • 42.
  • 43.
    List<Integer> li =new List<Integer>();
  • 44.
    May only takeInteger and subclasses, not Double
  • 45.
    ln = newList<Integer>(); // Compile error
  • 46.
    Not OK, Integercan not risk being a Double
  • 47.
    Generics – getprinciple Inheritance of generics classes is done with the extends and super wildcards
  • 48.
    To be ableto read from an inheritable generic class one must use the extends wildcard
  • 49.
    <? extends T> says that we can use any instance of the generic class that has been instantiated with the typ T or any subtypes of T class Reader<S> { S read(Reader<? extends S> r) { return r.read(); } Without this Reader<My> would only be able to read other Reader<My> instances. With extends it may also read for example Reader<MySub>
  • 50.
    Generics – putprinciple To be able to put stuff into a “inherited” generic type one has to use the super wildcard
  • 51.
    <? super T> say that any type that is a parent to T used to parameterized a generic class will make that class a subtype of the declaring class
  • 52.
    Look at List<? super Number> . What is List<Object>?
  • 53.
    Since Object isa supertype of Number List<Object> is a subtype of List<? super Number>!
  • 54.
    When writing thelimiting factor is the type to write (the thing you write into must be same type or a parent) static class Writer<D> { void write(Writer<? super D> w) { w.write(); } Without this Writer<My2> would not be able to write to a Writer<My>
  • 55.
    Generic – morecomplicated stuff Wildcard capture
  • 56.
    Wildcard not allowedat top level during instance creation
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
    New rule whenoverriding Old rule: a subclass can only override a method if it has the exact same signature
  • 63.
    To override public Object clone() one had to do it like this class Person { public Object clone() {} } Person pc = (Person) person.clone(); New rule: the return type may be a subtype of the type returned by the overridden method. Its now legal to do this: class Person { public Person clone() {} } Person pc = person.clone();
  • 64.
    Autoboxing Java typesystemprimitives which are NOT objects: int, byte, boolean...
  • 65.
    Objects inheriting fromjava.lang.Object
  • 66.
    Primitives have nocommon parent
  • 67.
    Autoboxing - primitivesPrimitives does not work well with Collections or any other class that work on Object void visit(String page) { int val = 0; if (stats.containsKey(page)) { val = ((Integer) stats.get(page)).intValue(); } Integer newVal = new Integer(++val) ; stats. put (page, newVal); }