The new features of Java 1.5

Download Report

Transcript The new features of Java 1.5

J2SE 5.0 New Features
J2SE 5.0 aka JDK 1.5 aka Tiger
What’s New
• J2SE 5.0 is full of dramatic changes to the
java programming language, including
new syntax support and JVM
enhancements.
• It is considered to be the most
revolutionary java release since JDK1.2
Today
•
•
•
•
•
•
Generics
Enhanced for Loop
Autoboxing \ Unboxing
Typesafe Enums
Varargs
Static Imports
For Each Statement
• A great way to ditch annoying Iterators.
Makes code more elegant and less error
prone.
• before
• after
Spot the Bug
Fixed Version
Using the For Each Statement
Iterating an Array
• The for-each construct can be used to
iterate arrays, hiding the index variable
instead of the iterator:
The Iterable Interface
• To make your own classes work with this
construct you should implement the
Iterable interface:
Autoboxing and Unboxing
• Autoboxing:
– Automatic converting of primitives into wrapper
classes
• Integer x = 10;
• Unboxing
– Automatic converting of wrapper classes into
primitives
• double PI = new Double(3.14);
Autoboxing and Unboxing
for (Integer i = 0;i < new Integer(10);) {
i++;
}
Boolean
Boolean
Boolean
Boolean
b1 = true;
b2 = true;
b3 = false;
result = (b1 || b2) && b3;
Example
Enums
• Previously, the standard way to represent
an enumerated type was to use the
int Enum pattern:
public
public
public
public
static
static
static
static
final
final
final
final
int
int
int
int
WINTER
SPRING
SUMMER
FALL
=
=
=
=
0;
1;
2;
3;
The int Enum Pattern - Problems
• Not TypeSafe
– you could add seasons or pass an arbitrary
season
• No Namespace
– With other enum types
• Uninformative printed values
• Can not add methods to enum values
The TypeSafe Enum Pattern
• Create a class with a private constructor.
Each enum value is a public static final
instance of the class.
• Major problem – cannot be used with
switch statements.
Java 1.5 Enums
enum Season{
WINTER, SPRING, SUMMER, FALL
}
Using the enum…
if (type == Season.WINTER)
System.out.println (…)
Java Enums are powerful features
• You can add arbitrary methods and fields
to enum types, implement interfaces, and
enjoy the existing implementation of the
Object class methods.
• Enums are Comparable and Serializable
Adding data to Enums
Adding data to Enums
• The enum type can be declared with a
constructor, and each enum constant is
declared with parameters to be passed to
the constructor.
Adding Behavior to Enum
Constants
• Using switch statements
Convert Switch statement to
polymorphism
Enums
• Enums are classes that extend java.lang.Enum.
• Each declared value is an instance of the enum.
• Enum values are public, static and final.
• Enums can be compared with == or equals().
• Implement several methods , ordinal(),
compareTo(), valueOf()
Varargs
• In past releases, if you wanted a method to get
an arbitrary number of arguments, it should have
been defined to receive an array.
• Alternatively you would have created several
overloaded methods.
• Tiger allows variable length argument list for its
methods, providing cleaner code with less
overloaded methods.
Varargs
• Varargs is done with the … operator.
• Example. The following constructor
public Person (String name, String details… )
Can be called with many different invocations:
new Person (“Alexander ”);
new Person (“Alexander ”, “Bell ”);
new Person (“Alexander ”,”Graham”, “Bell ”);
Varargs
• Accessing the varargs is done like accessing
arrays
public int sum (int... numbers) {
int result = 0;
for (int i = 0;i < numbers.length;i++) {
result+= numbers[i];
}
return result;
}
• Varargs can be used only in the final argument
position.
Varargs
• Before:
print( new String[] { “1”, “2”, “3” } );
...
private static void print( String[] array ) {
for ( int j = 0; j < array.length; j++ ) {
System.out.println( array [ j ] );
}
}
• After:
print( “1”, “2”, “3”, “4” ); // put as many as you need
...
private static void print( String ... array ) {
System.out.println ( array.length );
for ( String s : array ) {
System.out.println( s ); // same as array[ j ]
}
}
Static Imports
• In order to access static members, it is
necessary to qualify references with the class
they came from.
double r = Math.cos(Math.PI * theta);
• As a workaround people often put static
members as part of an interface and inherit from
that interface.
• This is known as the “Constant Interface
Antipattern”
Static Imports
• Using constants of another class is merely an
implementation detail. Declaring that a class
implements an interface is an API issue.
Implementation details should not leak into APIs.
• The static import construct allows you to access
static members of another class without
inheriting from the type containing them.
Static Imports
• members of another class are imported
import static java.lang.Math.PI;
• Once imported they can be used without
qualification
double r = cos(PI * theta);
Example
• Before
System.out.println(“Hello”);
System.out.println(“World”);
System.err.println(“From”);
System.err.println(“Me”);
• After
import static java.lang.System.*;
out.println(“Hello”);
out.println(“World”);
err.println(“From”);
err.println(“Me”);
Static Vs. Normal import
• Static imports are analogous to regular imports.
In normal imports you import classes from
packages, and in static imports you import static
class members out of classes.
• Use with care: only when frequent access is
required. It is suppose to improve readability,
and overuse may have an opposite effect.
Generics
• Generic Types have been widely anticipated by the java
community. The first place to see their use is in the
collections API.
• With Generics you can provide common functionality
with Type-safe Lists, Maps and Iterators for different java
types.
• Parameterized Types can also be defined as return
types and arguments.
• You can also write your own generic types.
Before Tiger
• Adding a String to a List
List list = new ArrayList();
list.add(new String(“Hello”);
list.add(new Integer(1));
list.add(new ArrayList());
• Must use casting to extract the String
String s = (String) list.get(0);
• Potential ClassCastException
String s = (String) list.get(1);
Generics With Tiger
• With Generics you construct real
homogenous collections.
List <String> list = new ArrayList<String>();
list.add(“One”);
list.add(“Two”);
list.add(“Three”);
• Extracting the contents no longer requires
casting
String one = list.get(0);
Generics
• Using casting the programmer is prone to a run
time error.
• With generics the programmer can express his
intent to have a homogenous data type.
• In the example the list was a generic interface
that took String as a type parameter.
• The significant difference is that now the
compiler can assure the type correctness at
compile time. we get improved robustness of our
code.
Parameterized types as Arguments
• public void foo( List<String> names)
Parameterized types as return
types
• public List<String> getNames();
Parameterized types as parameter
types
• public void bar
(Map <String, <List<Integers>>> map);
Defining Simple Generics
Defining Simple Generics
Invocation of Generic Types
• List<Integer> = new LinkedList<Integer>();
• You may imagine that List<Integer> stands for a
version of List where E has been replaced by
Integer:
public interface IntegerList {
void add(Integer x)
Iterator<Integer> iterator();
}
• This intuition is helpful, but also misleading.
Generics Vs. C++ Templates
• In java Generics, there is no real
expansion of code per type invocation.
• There are no multiple copies of the code,
not in source, not in binary, and not in
memory.
• A generic type declaration is compiled
once, and turned into a class file, just like
any ordinary class or interface declaration.
Generics and Subtyping
• Is the following code legal?
Compile time
Error
List<String> sList = new ArrayList<String>();
List<Object> oList = stringList;
• Is a list of Strings also A list of Objects?
oList.add(new Object());
String string = sList.get(0);
// attempt to assign an Object to a String
Generics and Subtyping
• Rule – if B is a subtype of A and G is some
generic type declaration then
G<B> is not a subtype of G<A>
• This is probably the most counter intuitive
rule of generics.
Wildcards – The need
• Consider a method that prints all the elements of a
But this version will not work
collection.
with all Collections,
old version
Only with Collection<Object>
which is not
a super type of all collections
first Attempt with generics
WildCards
• The super type of all collections is noted
as Collection<?>, pronounced “collection
of unknown”
Bounded Wildcards
What if we want to
pass List<Circle>
instead of
List<Shape>
Upper Bound of the Wildcard
• We say that the method receives a list of
unknown type that extends shape.
• Shape is the upper bound of the wildcard.
Generic Methods
• Consider a method that takes an object
array and a collection, and inserts all
elements of the array into the collection.
• First attempt:
Generic Methods
• Just like type declarations, method
declarations can be generic.
• Generic Methods are methods
parameterized by one or more type
parameter.
Generic Methods
• We don’t pass the actual type argument to
the method. It is inferred by the compiler
based on the most specific type argument
that will make the call type-correct.
Generic Methods
Wildcards support flexible subtyping
Type variables can have upper bounds too!
• For Polymorphic
method invocations,
i.e. If the return type
or other method
arguments are not
effected by the type
parameter T,
wildcards should be
preferred.
Generic Methods
• Use generic methods when you wish to
express dependencies among the
argument types or return types.
• Generic methods and wildcards can also
be used in tandem.
Interoperating with existing code
• How can legacy code and generic code
work together?
• When a generic type is used without a
type parameter, it’s called a raw type.
• There are many interesting implications of
combining generic and legacy code. Not in
today's scope.
Erasure and Translation
• Aliasing a generic list with a raw list.
• At runtime the code acts like this
• Both versions will end with a
ClassCastException.
Erasure and Translation
• Generics are implemented as a front-end
conversion called erasure. The generic version
is converted into a non generic version.
• All uses of type variables are replaced with
upper bound of the type variable, and whenever
the resulting code is not type correct, a cast is
inserted.
• As a result, the type safety of the Java Virtual
Machine are never at risk, even in the presence
of unchecked warnings.
A Generic class is Shared by all its
Invocations
List <String> l1 = new ArrayList<String>();
List <Integer> l2 = new ArrayList<Integer>();
System.out.println(l1.getClass() == l2.getClass());
• Returns True!!!
Casts and instanceOf
• You cannot ask an instance if it is an
instance of a particular type
• The runtime system will not check casts
such as
Lower bounded Wildcards
• Suppose you create a TreeSet of Strings. TreeSet<String>.
• We need to pass it a comparator that compares strings.
• But a comparator that compares Objects will also do. In fact
any super class of String is fine to use.
• Solution: lower bounded wildcards
Lower bounded Wildcards
• Consider a method that returns the
maximal element in a collection.
• The elements should be comparable, and
specifically to each other (to the collection
type).
• First Attempt:
Lower bounded Wildcards
• But consider the following class:
• All elements in the collection are comparable to each
other, but the inferred type must be Foo, which does not
implement Comparable<Foo>
• T does not have to be comparable exactly to itself, it is
only required that it is comparable to one of its
superclasses.
Bounding Rules
• If the API only uses a type parameter as
an argument you should take advantage
of lower bounded wildcards (? super T)
• If the API only returns T, clients will enjoy
the flexibility if you provide them upper
bounded wildcards (? extends T)
Converting Existing Code to
Generics
• Naïve conversions may unintentionally modify the API
contract. Notice that the non generic version of containsAll
could work with any collection, while the generic one will not.
• Should the argument type be restricted? Could we pass a
collection of a subtype of E?
• In the case of addAll we should assure that the method works
with a collection containing sub types of E
Converting Existing Code to
Generics
• Recall the Collections.max() method
But the erasure of this method is
Which is different then the original signature
of max()
Giving multiple bounds for a type
parameter
• Using the Syntax T1 & T2 & … Tn, a type
variable is assigned with multiple bounds
and is known to be a subtype of all the
listed types.
• The first type mentioned in the bound is
used as the erasure of the type variable.
More Features
• Annotations
• Overriding methods return types. (Covariant Typing)
• printf-like formatting methods.
• New default Java look & feel.
• Parallel GC by default on server machines
• Class Data Sharing (CDS)
• Threading issues are boosted in Tiger.
Getting Started
• Get a J2SE 5.0 supported IDE:
– NetBeans 4.0
– IDEA IntelliJ 4.5
– “Cheetah” – eclipse 3.0 plugin