57
Key Componen ts of Java Key Components of Java 1.5 1. 5 (1.6) (1.6) CMSC 432

Key Components of Java 1.5 (1.6) CMSC 432. 2 Reason for changes “The new language features all have one thing in common: they take some common idiom and

Embed Size (px)

Citation preview

Key Components of Ja

va 1.5

Key Components of Ja

va 1.5

(1.6)(1.6)

CMSC 432

2

Reason for changesReason for changes

• “The new language features all have one thing in common: they take some common idiom and provide linguistic support for it. In other words, they shift the responsibility for writing the boilerplate code from the programmer to the compiler.”

--Joshua Bloch, senior staff engineer, Sun Microsystems

3

New featuresNew features

• Enhanced for loop– Automates use of Iterators to avoid errors

• Autoboxing/unboxing– Avoids manual conversion between primitive types (such as int)

and wrapper types (such as Integer)• Typesafe enums

– Provides all the well-known benefits of the Typesafe Enum pattern

• Generics– Compile-time type safety for collections without casting

• Scanner class API for easier text input– Easier basic input functionality

• Formatted I/O

4

IteratorsIterators

• An iterator gives you every element of a collection, one at a time– The collection has a type iterator(); factory method to

return a new iterator to return objects of the given type– The method boolean hasNext() tells you if there are

more objects– The method type next() returns the next object– The method void remove() deletes the last object gotten

• Example:– Iterator iter = integerStack.iterator();

while (iter.hasNext()) { System.out.println(iter.next());}

5

Enhanced Enhanced forfor loop loop• Instead of

void cancelAll(Collection c) { for (Iterator i = c.iterator(); i.hasNext(); ) { TimerTask tt = (TimerTask) i.next(); tt.cancel(); } }

• You will be able to use: void cancelAll(Collection<TimerTask> c) { for (TimerTask task : c) task.cancel(); }– What does the JDK 1.5 compiler handle automatically for us?– Not everyone likes this syntax! How else could it have been

done? void cancelAll(Collection<TimerTask> c) { foreach TimerTask task of c) //C# notation task.cancel(); }

6

AutoboxingAutoboxing• Java distinguishes between primitive types and Objects

– Primitive types, i.e., int, double, are compact, support arithmetic operators

– Object classes (Integer, Double) have more methods: Integer.toString()

– You need a “wrapper” to use Object methods: Integer ii = new Integer( i ); ii.hashCode()

– Similarly, you need to “unwrap” an Object to use primitive operation

int j = ii.intValue() * 7;• Java 1.5 makes this automatic:

– Before:ArrayList<Integer> list = new ArrayList<Integer>(); list.add(0, new Integer(42)); int total = (list.get(0)).intValue();

– After:ArrayList<Integer> list = new ArrayList<Integer>(); list.add(0, 42); int total = list.get(0);

7

Java Java

Enumerations

Enumerations

8

EnumerationsEnumerations

• An enumeration, or “enum,” is simply a set of constants to represent various values

• Here’s the old way of doing it:public final int SPRING = 0;public final int SUMMER = 1;public final int FALL = 2;public final int WINTER = 3;

• This is a nuisance, and is error prone as well• Here’s the new way of doing it:

enum Season { winter, spring, summer, fall }

9

Advantages of the new Advantages of the new enum?enum?

• They provide compile-time type safety– int enums don't provide any type safety at all

• They provide a proper name space for the enumerated type– With int enums you have to prefix the constants to get any

semblance of a name space.

• They're robust– int enums are compiled into clients, and you have to recompile

clients if you add, remove, or reorder constants.

• Printed values are informative– If you print an int enum you just see a number.

• Because they're objects, you can put them in collections.• Because they're essentially classes, you can add arbitrary

fields and methods

10

EnumsEnums

• An enum type is a type whose fields consist of a fixed set of constants. Common examples:– directions (values of NORTH, SOUTH, EAST, and WEST)– days of the week

• In the Java programming language, you define an enum type by using the enum keyword. For example, you would specify a days-of-the-week enum type:

public enum Day { SUNDAY, MONDAY, TUESDAY,

WEDNESDAY, THURSDAY, FRIDAY, SATURDAY }

11

Using EnumsUsing Enums

public class EnumTest { Day day;

public EnumTest(Day day) {this.day = day;

}

public void tellItLikeItIs() {switch (day) {case MONDAY: System.out.println("Mondays stink.");

case SATURDAY:case SUNDAY: System.out.println("Weekends are best.");

break;

default: System.out.println("Midweek days are so-so."); break;

} }

12

Using Enums (Cont)Using Enums (Cont)

public static void main(String[] args) {

EnumTest firstDay = new EnumTest(Day.MONDAY); firstDay.tellItLikeItIs();

EnumTest seventhDay = new EnumTest(Day.SUNDAY); seventhDay.tellItLikeItIs();

}

13

Defining an EnumDefining an Enum

• In Java enums declaration define a class (called an enum type).

• The enum class body can include methods and

other fields.

public enum Planet { MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6), EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6), JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7), URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7);

private final double mass; // in kilograms private final double radius; // in meters

Planet(double mass, double radius) { this.mass = mass; this.radius = radius; } private double mass() { return mass; } private double radius() { return radius; } // universal gravitational constant (m3 kg-1 s-2) public static final double G = 6.67300E-11;

double surfaceGravity() { return G * mass / (radius * radius); } double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } } for (Planet p : Planet.values()) {

System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass));}New style for loop

C+ printf i/o

Constructor

Method

Java Generics

Java Generics

A Key Component in Ja

va 1.5

A Key Component in Ja

va 1.5

15

ConceptsConcepts

• Generalizing Collection Classes• Using Generics with other Java 1.5

Features• Integration of Generics with Previous

Releases• User built generic classes

16

What Are Generics?What Are Generics?

• Generics abstract over Types• Classes, Interfaces and Methods can

be Parameterized by Types• Generics provide increased

readability and type safety

17

Java Generic ProgrammingJava Generic Programming

• Java has class Object– Supertype of all object types– This allows “subtype polymorphism”

• Can apply operation on class T to any subclass S <: T

• Java 1.0 – 1.4 do not have templates – No parametric polymorphism– Many consider this the biggest deficiency of Java

• Java type system does not let you cheat– Can cast from supertype to subtype– Cast is checked at run time

18

Example generic construct: Example generic construct: StackStack

• Stacks possible for any type of object– For any type t, can have type stack_of_t– Operations push, pop work for any type

• In C++, would write generic stack classtemplate <type t> class Stack {

private: t data; Stack<t> * next;public: void push (t* x) { … }

t* pop ( ) { … } };

• What can we do in Java?

19

Simple Example Using Simple Example Using InterfacesInterfaces

interface List<E> { void add(E x);

Iterator<E> iterator();}interface Iterator<E> {

E next(); boolean hasNext();

}

20

What Generics Are NotWhat Generics Are Not

• Generics are not templates• Unlike C++, generic declarations are

– Typechecked at compile time– Generics are compiled once and for all

• Generic source code not exposed to user• No bloat

The type checking with Java 1.5 Generics The type checking with Java 1.5 Generics changes the way one programschanges the way one programs(as the next few slides show)(as the next few slides show)

The type checking with Java 1.5 Generics The type checking with Java 1.5 Generics changes the way one programschanges the way one programs(as the next few slides show)(as the next few slides show)

21

Java 1.0 vs GenericsJava 1.0 vs Generics

class Stack { void push(Object o) { ... } Object pop() { ... } ...}

String s = "Hello";Stack st = new Stack(); ...st.push(s);...s = (String) st.pop();

class Stack<A> { void push(A a) { ... } A pop() { ... } ...}

String s = "Hello";Stack<String> st = new Stack<String>();st.push(s);...s = st.pop();

22

Java generics are type Java generics are type checkedchecked

• A generic class may use operations on objects of a parameter type– Example: PriorityQueue<T> … if x.less(y) then

• Two possible solutions– C++: Link and see if all operations can be

resolved– Java: Type check and compile generics w/o linking

• This requires programmer to give information about type parameter

• Example: PriorityQueue<T extends ...>

23

How to Use GenericsHow to Use Generics

List<Integer> xs = new LinkedList<Integer>();

xs.add(new Integer(0));Integer x = xs.iterator.next();

Compare with

List xs = new LinkedList();xs.add(new Integer(0));Integer x = (Integer)xs.iterator.next();

24

Collection Class ExampleCollection Class Example

HashMap<Intger, Double> hm = new HashMap<Intger,

Double> ();

// Note Auto-boxing from 15.hm.put (1,2.0);double coeff = hm.get(1);

Hashmap1.4 hm => Hashmap1.5<Object, Object>Hashmap1.4 hm => Hashmap1.5<Object, Object>

25

List Usage: Without GenericsList Usage: Without Generics

List ys = new LinkedList();ys.add("zero");List yss;yss = new LinkedList();yss.add(ys);String y = (String)((List)yss.iterator().next()).iterator().next();

// EvilEvil run-time errorrun-time errorInteger z = (Integer)ys.iterator().next();

26

List Usage: With GenericsList Usage: With Generics

List<String> ys = new LinkedList<String>();ys.add("zero");List<List<String>> yss;yss = new LinkedList<List<String>>();yss.add(ys);String y =

yss.iterator().next().iterator().next();

// Compile-time error – much better!Integer z = ys.iterator().next();

27

List Implementation w/o List Implementation w/o GenericsGenerics

class LinkedList implements List {protected class Node {

Object elt;Node next;Node(Object elt){elt = e; next = null;}

}protected Node h, t;public LinkedList() {h = new Node(null); t = h;}public void add(Object elt){

t.next = new Node(elt);t = t.next;

}}

Inner ClassRemember these?

Inner ClassRemember these?

28

List Implementation With List Implementation With GenericsGenerics

class LinkedList<E >implements List<E>protected class Node {E elt;Node next;

Node(E elt){elt = e; next = null;} }protected Node h, t;public LinkedList() {h = new Node(null); t = h;}public void add(E elt){

t.next = new Node(elt);t = t.next;

}// …

}

29

Recall the Interator InterfaceRecall the Interator Interface

class LinkedList<E >implements List<E>– // …public Iterator<E> iterator(){

return new Iterator<E>(){protected Node p = h.next;public boolean hasNext(){return

p != null;}public E next(){

E e = p.elt;p = p.next;return e;

}}

}}

30

Methods Can Be Generic AlsoMethods Can Be Generic Also

interface Function<A,B>{ B value(A arg);}

interface Ntuple<T> {<S> Ntuple<S> map(Function<T,S> f);

}Ntuple<Integer> nti = ....;nti.map (new Function<Integer, Integer> {

Integer value(Integer i) {return new

Integer(i.intValue()*2);}

});

31

Example: Generics and Example: Generics and InheritenceInheritence

11stst consider this code w/o Generics consider this code w/o Genericsclass ListUtilities {

public static Comparable max(List xs) {Iterator xi = xs.iterator();Comparable w = (Comparable) xi.next();while (xi.hasNext()) {

Comparable x = (Comparable) xi.next();if (w.compareTo(x) < 0) w = x;

}return w;

}} What dangers lurk here?What dangers lurk here?

32

Consider what happens (and Consider what happens (and when)when)

List xs = new LinkedList();xs.add(new Byte(0));Byte x = (Byte) ListUtilities.max(xs);List ys = new LinkedList();ys.add(new Boolean(false));

// EvilEvil run-time errorrun-time error Boolean y = (Boolean) ListUtilities.max(ys);

33

With Generics We Get Compile With Generics We Get Compile CheckCheck

List<Byte> xs = new LinkedList<Byte>();xs.add(new Byte(0));Byte x = ListUtilities.max(xs);List<Boolean> ys = new

LinkedList<Boolean>();ys.add(new Boolean(false));

// Compile-time errorBoolean y = ListUtilities.max(ys);

34

Generics and InheritenceGenerics and Inheritence

• Suppose you want to restrict the type parameter to express some restriction on the type parameter

• This can be done with a notion of subtypes• Subtypes (weakly construed) can be

expressed in Java using inheritance• So it’s a natural combination to combine

inheritance with generics• A few examples follow

35

Priority Queue ExamplePriority Queue Example

interface Comparable<I> { boolean lessThan(I); }

class PriorityQueue<T extends Comparable<T>> {

T queue[ ] ; … void insert(T t) { ... if ( t.lessThan(queue[i]) ) ... } T remove() { ... } ... }

Said to be boundedSaid to be bounded

36

Bounded Parameterized Types Bounded Parameterized Types

• The <E extends Number> syntax means that the type parameter of MathBox must be a subclass of the Number class– We say that the type parameter is bounded

new MathBox<Integer>(5); //Legalnew MathBox<Double>(32.1); //Legalnew MathBox<String>(“No good!”);//Illegal

37

Bounded Parameterized Types Bounded Parameterized Types

• Inside a parameterized class, the type parameter serves as a valid type. So the following is valid.

public class OuterClass<T> {

private class InnerClass<E extends T> { … } …}

Syntax note: The <A extends B> syntax is valid even if B is an interface.

38

Bounded Parameterized TypesBounded Parameterized Types

• Java allows multiple inheritance in the form of implementing multiple interfaces, so multiple bounds may be necessary to specify a type parameter. The following syntax is used then:

<T extends A & B & C & …>

• Exampleinterface A {…}interface B {…}

class MultiBounds<T extends A & B> {…}

39

Another example …Another example … interface LessAndEqual<I> { boolean lessThan(I); boolean equal(I); }class Relations<C extends LessAndEqual<C>> extends C { boolean greaterThan(Relations<C> a) { return a.lessThan(this); } boolean greaterEqual(Relations<C> a) { return greaterThan(a) || equal(a); } boolean notEqual(Relations<C> a) { ... } boolean lessEqual(Relations<C> a) { ... } ... }

40

Generics and SubtypingGenerics and Subtyping

• Is the following code snippet legal?List<String> ls = new ArrayList<String>(); //1List<Object> lo = ls; //2

• Line 1 is certainly legal. What about line 2? Is a List of Strings a List of Object. Intuitive answer for most is “sure!”. But wait!

• The following code (if line 2 were allowed) would attempt to assign an Object to a String!

lo.add(new Object()); // 3String s = ls.get(0); // 4:For all types P and C (i.e C is a subtype of P)

Subtype(P,C) !=> Subtype(Generic<P>,Generic<C>)For all types P and C (i.e C is a subtype of P)

Subtype(P,C) !=> Subtype(Generic<P>,Generic<C>)

41

Subclassing a generic classSubclassing a generic class

import java.awt.Color;

public class Subclass extends MyClass<Color> {

// You almost always need to supply a constructor public Subclass(Color color) { super(color); }

public static void main(String[ ] args) { Subclass sc = new Subclass(Color.GREEN); sc.print(Color.WHITE); }

}

42

WildcardsWildcards

• Consider the problem of writing code that prints out all the elements in a collection before 1.5.

void printCollection(Collection c) { Iterator i = c.iterator();for (k = 0; k < c.size(); k++) { System.out.println(i.next());}

}

43

11stst Naïve Try w/ Generics Naïve Try w/ Generics

void printCollection(Collection<Object> c) { for (Object e : c) {

System.out.println(e);}

}• The problem is that this new version is much less

useful than the old one. • The old code could be called with any kind of

collection as a parameter, • The new code only takes Collection<Object>,

which, as is not a supertypeof all kinds of collections!

44

Correct way – Use WildcardsCorrect way – Use Wildcards

• So what is the supertype of all kinds of collections? • Pronounced “collection of unknown” and denoted

Collection<?>, • A collection whose element type matches anything.• It’s called a wildcard type for obvious reasons. void printCollection(Collection<?> c) {

for (Object e : c) { System.out.println(e);

}}

45

Using Wildcards AgainUsing Wildcards Again

public class Census { public static void

addRegistry(Map<String, ? extends Person> registry) { ...}

}...// Assuming Drivers are a subtype of PersonMap<String, Driver> allDrivers = ...;Census.addRegistry(allDrivers);

46

Implementing GenericsImplementing Generics

• Type erasure– Compile-time type checking uses generics– Compiler eliminates generics by erasing them

• Compile List<T> to List, T to Object, insert casts

• “Generics are not templates”– Generic declarations are typechecked– Generics are compiled once and for all

• No instantiation• No “code bloat”

47

How Do Generics Affect My How Do Generics Affect My Code?Code?

• They don’t – except for the way you’ll code!

• Non-generic code can use generic libraries;

• For example, existing code will run unchanged with generic Collection library

48

ErasureErasure

• Erasure erases all generics type argument information at compilation phase.– E.g. List<String> is converted to List– E.g. String t = stringlist.iterator().next() is

converted to String t = (String) stringlist.iterator().next()

• As part of its translation, a compiler will map every parameterized type to its type erasure.

49

ErasureErasure

• List <String> l1 = new ArrayList<String>();

• List<Integer> l2 = new ArrayList<Integer>();

• System.out.println(l1.getClass() == l2.getClass());

Wrap UpWrap UpQuestionsQuestions?QuestionsQuestions?

51

ReferencesReferences

• http://www.stanford.edu/class/cs242/slides/2004/java.ppt

• Adding Generics to the Java™ Programming Language, Gilad Bracha.Talk TS-2733Java One Conference 2001

• Gilad Bracha. Generics in the Java Programming Language. http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

• http://www.cs.tut.fi/~kk/webstuff/MetaProgrammingJavaKalvot.pdf

• http://www.lips.dist.unige.it/corsi/lsp1/dispense/LSP1-Succi-3.ppt

• http://www.cis.upenn.edu/~matuszek/cit597-2003/.../46-java-1.5.ppt

52

Additional SlidesAdditional Slides

53

Scanner classScanner class

• Provides basic input functionality for reading data from system console or any data stream

• Following example reads a String from standard input and expects a following int value:

Scanner s=Scanner.create(System.in); String param= s.next(); int value=s.nextInt(); s.close();

– Scanner methods next and nextInt block if no data is available

– Supports regular expression based search

• To process more complex input, pattern matching algorithms are available from class java.util.Formatter

54

Formatted outputFormatted output

• Similar to C/C++ printf and scanf:System.out.printf("name count%n"); //newlineSystem.out.printf("%s %5d%n", user,total);

• See the java.util.Formatter class for more information • Supports formats for dates, etc:

System.out.format("Local time: %tT",Calendar.getInstance()); // -> "Local time: 13:34:18"

• Like C's sprintf(3), Strings may be formatted using String.format: import java.util.Calendar; import java.util.GregorianCalendar; import static java.util.Calendar.*; Calendar c = new GregorianCalendar(1995, MAY, 23); String s = String.format("Duke's Birthday: %1$tm %1$te,%1$tY", c); // -> s == "Duke's Birthday: May 23, 1995"

55

Variable ArgumentsVariable Arguments• Prior to Java 1.5, passing a variable number of

arguments to a method required explict array creation

• You could create an array variable initialized to the array and pass that variable to a method, as in – String [] s = { "first", "second", "third" };

printStrings (s);

• Java 1.5 overcomes this problem by introducing the new variable arguments language feature.

• To use variable arguments, conform the parameter list's rightmost parameter to the following syntax: – type ... variableName

56

ExampleExample• Avg class

public class Avg {

public static void main (String [] args) { System.out.println (avg ()); System.out.println (avg (1, 2, 3)); }

public static int avg (int ... integers) {

int sum = 0; for (int i = 0; i < integers.length; i++) sum += integers [i]; return (integers.length != 0) ? sum / integers.length : 0; } }

57

Variable ArgumentsVariable Arguments

• During compilation, the Java compiler converts the new parameter syntax to the old array parameter syntax.

• This means you can invoke printStrings() using – printStrings (new String [] { "first", "second", "third" });

• or using – printStrings ("first", "second", "third");

• However, if you declare printStrings() with the old String [] s parameter syntax and then invoke the method using printStrings ("first", "second", "third");, the compiler reports an error