assertions (since java 1.5) - wordpress.com · an inner class is a class declared inside another...

33
Assertions (since Java 1.5) assert <boolean expression>; assert <boolean expression> : <message expression>; AssertionError by default disabled at runtime javac –ea/da [:package name] OR [:class name] Internal invariants assert time>0; Control Flow invariants assert false : “should not be reached”; Preconditions and Postconditions

Upload: others

Post on 09-Aug-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Assertions (since Java 1.5)

assert <boolean expression>;

assert <boolean expression> : <message expression>;

AssertionError

by default disabled at runtime

javac –ea/da [:package name] OR [:class name]

Internal invariants assert time>0;

Control Flow invariants assert false : “should not be reached”;

Preconditions and Postconditions

Page 2: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere
Page 3: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Rember the lab public class Computer {

private int ram;

private String processor;

public Computer(int ram, String processor) throws

Exception {

if(ram!=2 && ram!=4 && ram!=8) {

throw new Exception("Bad value for RAM");

}

if(!processor.equals("i3") &&

!processor.equals("i5") && !processor.equals("i7")) {

throw new Exception("Bad value for

processor");

}

this.ram = ram;

this.processor = processor;

}

Page 4: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Solution 1

public class Computer {

public static final int I3=1;

public static final int I5=2;

public static final int I7=3;

if(processor!=I3 && processor!=I5 &&

processor!=I7 {

throw new Exception("Bad value

for processor");

}

Page 5: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Solution 2 public class Processor {

public static final int I3=1;

public static final int I5=2;

public static final int I7=3;

}

public class Computer {

if(processor!=Processor.I3)…

Cons • Not typesafe => any int value can be used

• Only the value is printed, not its name

Page 6: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Enum type

An enumerated type defines a set of symbolic names and their values.

Typesafe Enums

enum Processor {I3, I5, I7}

Processor = type name

I3, I5, I7 = enum constants

Can be passed as arguments, can be declared as references

Cannot be instantiated

Page 7: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Using Enum types Processor.java

public enum Processor {I3, I5, I7}

Computer.java

public class Computer {

private Processor processor;

public Computer(Ram ram, Processor processor) throws

Exception {

if(processor!=Processor.I3 && processor!=Processor.I5 &&

processor!=Processor.I7) { //No longer necessary

Page 8: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Enum constructors and members public enum Currency{

RON(4.56), DOLLAR(1.4), EURO(1);

private double raportEuro;

Currency(double re){ //private constructor

raportEuro=re;

}

public void changeEuroRaport(double re){

raportEuro=re;

}

public double getRaportEuro(){

return raportEuro;

}

public static void main(String[] args){

Currency.DOLLAR.changeEuroRaport(1.3991);

System.out.println("The Euro-Dolar parity is

"+Currency.DOLLAR.getRaportEuro());

}

}

Page 9: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Methods inherited from Enum class

static EnumTypeName[] values()

Returns an array containing the enum constants of this enum type, in the order they are specified.

static EnumTypeName valueOf(String

name)

Returns the enum constant with the specified name. An IllegalArgumentException is thrown if the specified name does not match the name of an enum constant.

Page 10: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

protected final Object clone()

An instance of an enum type cannot be cloned, throws an CloneNotSupportedException.

final int compareTo(E o)

Implements Clonable<E>, the natural order of the enum constants in an enum type is according to their ordinal values

final boolean equals(Object other)

true if the specified object is equal to this enum constant

final String name()

Returns the name of this enum constant, as declared in its enum declaration.

final int ordinal()

This method returns the ordinal value of this enum constant (that is, its position in its enum type declaration). The first enum constant is assigned an ordinal value of 0.

Page 11: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Example public static void main(String[] args){

Currency.DOLLAR.changeEuroRaport(1.3991);

System.out.println("The Euro-Dolar parity is

"+Currency.DOLLAR.getRaportEuro());

for(Currency c : Currency.values())

System.out.println(c.name()); //RON,EURO, DOLLAR

System.out.println(Currency.valueOf("DOLLAR"));

//DOLLAR

System.out.println(Currency.DOLLAR.ordinal()); //1

}

Page 12: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Nested Classes

An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere in a program.

Four categories of nested classes, defined by the context they are defined in:

• Static member classes, enums, interfaces

• Non-static member classes

• Local classes

• Anonymous classes

Inner classes

Page 13: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Nested Type Declaration public class TopLevel { //Top level class

static class SMC {} //Static member class

interface SMI {} //Static member interface

class IC {} //Non-static member (inner) class

void nsm(){

class NSLC {} //Local inner class in non-static context

}

static void sm(){

class SLC{} //Local inner class in static context

}

method(new SMC(){…});

//Anonymous class in non-static context

static method(new SMI(){…});

//Anonymous class in static context

}

Page 14: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Inner Classes

There are four reasons to use inner classes:

1. An object of an inner class can access the implementation of the object that created it - including data that would otherwise be private.

2. Inner classes can be hidden from other classes in the same package.

3. Anonymous inner classes are handy when you want to define callbacks on the fly.

4. Inner classes are very convenient when you are writing event-driven programs.

Page 15: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Using an Inner Class to Access Object State (I)

Consider the case where a timer controls a bank account. The timer's action listener object adds interest to the account once every time interval. We don't want to use public methods (such as deposit or withdraw) to manipulate the bank balance, instead, we will use an inner class whose methods can manipulate the bank balance directly.

class BankAccount{ // outer class

private double balance;

public BankAccount(double initialBalance){ balance = initialBalance; }

private class InterestAdder implements ActionListener { // inner class

private double rate;

public InterestAdder(double aRate) {

rate = aRate;

}

public void actionPerformed(ActionEvent event) {

. . .

}

}

public void start(double rate) { . . . }

}

We will construct objects of the inner class, but those objects aren't instance fields of the outer class. Instead, they will be local to the methods of the outer class.

Page 16: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Using an Inner Class to Access Object State (II)

public void start(double rate){

ActionListener adder = new InterestAdder(rate);

Timer t = new Timer(10000, adder);

t.start();

}

As a result, the actionPerformed method of the InterestAdder class will be called once every 10 seconds. public void actionPerformed(ActionEvent event){

double interest = balance * rate / 100;

balance += interest;

System.out.println("balance=“ + balance);

}

An inner class object has a reference to an outer class object. Let call it outer. This reference is invisible in the definition of the inner class.

outer=

InterestAddert

balance=

BankAccount

rate=

Page 17: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Using an Inner Class to Access Object State (III)

public void actionPerformed(ActionEvent event){

double interest=outer.balance*this.rate/100;

//"outer" isn't the actual name

outer.balance += interest;

System.out.println("balance=“ + balance);

}

The outer class reference is set by the compiler in the constructor. That is, it adds a parameter to the constructor, generating code like this: public InterestAdder(BankAccount account, double aRate){

outer = account; // automatically generated code

rate = aRate;

}

When an InterestAdder object is constructed in the start method, the compiler passes the this reference to the current bank account into the constructor: ActionListener adder = new InterestAdder(this, rate);

// automatically generated code

Page 18: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Syntax Rules for Inner Classes

The proper syntax for the outer reference is more complex. The expression OuterClass.this denotes the outer class reference. We can write:

public void actionPerformed(ActionEvent event){

double interest = BankAccount.this.balance * this.rate / 100;

BankAccount.this.balance += interest;

. . .

}

you can write the inner object constructor more explicitly, using the syntax:

outerObject.new InnerClass(construction parameters)

For example, ActionListener adder = this.new InterestAdder(rate);

You can refer to an inner class as OuterClass.InnerClass when it occurs outside the scope of the outer class.

For example, if InterestAdder had been a public class, you could have referred to it as:

BankAccount mySavings = new BankAccount(10000);

BankAccount.InterestAdder adder = mySavings.new InterestAdder(10);

Page 19: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Local Inner Classes (I)

public void start(final double rate){

class InterestAdder implements ActionListener {

private double rate;

public InterestAdder(double aRate) {

rate = aRate;

}

public void actionPerformed(ActionEvent event) {

double interest = balance * rate / 100;

balance += interest;

System.out.println("balance=" + balance);

}

}

ActionListener adder = new InterestAdder(rate);

Timer t = new Timer(1000, adder);

t.start();}

Local classes are completely hidden from the outside world. They are never declared with an access specifier (that is, public or private). Their scope is always restricted to the block in which they are declared.

Not only can they access the fields of their outer classes, they can even access local variables! However, those local variables must be declared final.

Page 20: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Local Inner Classes (II) The InterestAdder class no longer needs to store a rate instance variable. It simply

can refer to the parameter variable of the method that contains the class definition.

public void start(final double rate){

class InterestAdder implements ActionListener {

public void actionPerformed(ActionEvent event) {

double interest = balance * rate / 100;

balance += interest;

System.out.println("balance=“ + balance);

}

}

ActionListener adder = new InterestAdder();

Timer t = new Timer(10000, adder);

t.start();

}

Let's consider the flow of control : 1. The start method is called. 2. The object variable adder is initialized via a call to the constructor of the

inner class InterestAdder. 3. The adder reference is passed to the Timer constructor, the timer is started,

and the start method exits. At this point, the rate parameter variable of the start method no longer exists.

4. A second later, the actionPerformed method calls double interest = balance * rate / 100;.

Page 21: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Anonymous inner classes

If we want to make only a single object of this class, we don't even need to give the class a name. Such a class is called anonymous inner class.

public void start(final double rate){

ActionListener adder = new ActionListener() {

public void actionPerformed(ActionEvent event){

double interest = balance * rate / 100;

balance += interest;

System.out.println("balance=“ + balance);

}

};

Timer t = new Timer(1000, adder);

t.start();

}

In general, the syntax is: new SuperType(construction parameters){

inner class methods and data

}

SuperType can be an interface, such as ActionListener; then, the inner class implements that interface. Or, SuperType can be a class; then, the inner class extends that class.

An anonymous inner class cannot have constructors.

Page 22: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Extending Inner Classes OuterA

OuterB

SubclassC

InnerB

InnerA

public class OuterA {

class InnerA {}

}

public class SubclassC extends OuterA.InnerA{

SubclassC(OuterA outerRef){ //Non-default

outerRef.super(); //Explicit super() call

}

}

Page 23: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Extending Inner Classes

public class OuterB extends OuterA{

class InnerB extends OuterA.InnerA{}

}

public class Main {

public static void main(String[] args) {

SubclassC sc=new SubclassC(new OuterA());

OuterB.InnerB bb=new OuterB().new InnerB();

}

}

Page 24: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Revision visibility public class TopLevel {

private int f1;

static private int f2;

static class SMC {} //f2

interface SMI {}

class IC {} //f1,f2

void nsm(){

final int f3;

class NSLC {} //f1,f2,f3

}

static void sm(){

final int f4;

class SLC{} //f2,f4

}

TopLevel.SMC tsmc=new TopLevel.SMC();

TopLevel.IC tic=new TopLevel().new IC(); //OR

TopLevel tc=new TopLevel();

TopLevel.IC tic2=tc.new IC();

Page 25: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Generics

Generics allow you to abstract over types. Generic programming means to write code that can be reused for objects of many different types.

A way to make classes type-safe that are written to work on any arbitrary object type, such as narrowing an instance of a collection to hold a specific object type and eliminating the need to cast objects when taking an object out of the collection.

Page 26: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

A Simple Box Class A non-generic Box Class public class Box { private Object object; public void add(Object object) { this.object = object; } public Object get() { return object; } }

Use correctly a Box of Integer objects public class BoxDemo1 { public static void main(String[] args) { // ONLY place Integer objects into this box! Box integerBox = new Box(); integerBox.add(new Integer(10)); Integer someInteger = (Integer)integerBox.get(); System.out.println(someInteger); } }

Use erroneously a Box of Integer objects public class BoxDemo2 { public static void main(String[] args) { // ONLY place Integer objects into this box! Box integerBox = new Box(); // Imagine this is one part of a large application // modified by one programmer. integerBox.add("10"); // the type is now String // perhaps written by a different programmer Integer someInteger = (Integer)integerBox.get(); System.out.println(someInteger); } } Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer at BoxDemo2.main(BoxDemo2.java:6)

If the Box class had been

designed with generics in

mind, this mistake would

have been caught by the

compiler, instead of

crashing the application

at runtime.

This is clearly a bug,

but because the code

still compiles, you

wouldn't know anything

is wrong until runtime

when the application

crashes

Page 27: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

A Generic Box Class

public class Box<T> {

private T t; // T stands for "Type" public void add(T t) { this.t = t; } public T get() { return t; } }

To reference this generic class from within your code, you must perform a

generic type invocation, which replaces T with a concrete type as Integer. Box<Integer> integerBox;

To instantiate this class use: integerBox = new Box<Integer>(); //Or in Java 7 new Box<>();

You're free to invoke its get method without providing a cast: public class BoxDemo3 {

public static void main(String[] args) {

Box<Integer> integerBox = new Box<Integer>();

integerBox.add(new Integer(10));

Integer someInteger = integerBox.get(); // no cast!

System.out.println(someInteger);

}

}

If you try adding an incompatible type to the box, such as String, compilation will fail, alerting you to what previously would have been a runtime bug:

BoxDemo3.java:5: add(java.lang.Integer) in Box<java.lang.Integer> cannot be applied to (java.lang.String)

integerBox.add("10"); ^ 1 error

Page 28: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Why Generic Programming? Before JDK 5.0

public class ArrayList {

private Object[] elementData;

public Object get(int i) { . . . }

public void add(Object o) { . . . } . . . }

This approach has two problems. 1. A cast is necessary whenever you retrieve a value: ArrayList files = new ArrayList(); . . . . . .

String filename = (String) files.get(0);

2. Moreover, there is no error checking. You can add values of any class: files.add(new File(". . ."));

Compilation without error, but casting to a String will cause a cast exception Beginning with JDK 5.0 The ArrayList class has a type parameter that indicates the element type:

ArrayList<String> files = new ArrayList<String>();

1. You can tell right away that this particular array list contains String objects. 2. The compiler can make good use of this information too. No cast is

required for calling get: the compiler knows that the return type is String, not Object:

String filename = files.get(0);

The compiler also knows that the add method of an ArrayList<String> has a parameter of type String. That is safer than having an Object parameter. Now the compiler can check that you don't insert objects of the wrong type.

For example, the statement files.add(new File(".."));

will not compile. A compiler error is much better than a class cast exception.

Page 29: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Generic Classes A generic class is a class with one or more type variables. Let consider a simple Pair class: public class Pair<T> {

private T first;

private T second;

public Pair() { first = null; second = null; }

public Pair(T first, T second) {this.first=first; this.second=second;}

public T getFirst() { return first; }

public T getSecond() { return second; }

public void setFirst(T newValue) { first = newValue; }

public void setSecond(T newValue) { second = newValue; }

}

A generic class can have more than one type variable. public class Pair<T, U> { . . . }

The type variables are used throughout the class definition to specify method return types and the types of fields and local variables. For example,

private T first; // uses type variable

The generic type is instantiated by substituting types for the type variables: Pair<String>

You can think of the result as an ordinary class with constructors : Pair<String>()

Pair<String>(String, String)

and methods String getFirst() String getSecond() void setFirst(String)

void setSecond(String)

The generic class acts as a factory for ordinary classes.

Page 30: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Generic Methods (I) Type parameters can also be declared within method and constructor

signatures to create generic methods and generic constructors. In this case the type parameter's scope is limited to the method or constructor in which it's declared. . class ArrayAlg {

public static <T> T getMiddle(T[] a) {

return a[a.length/2]);

}

}

This method is defined inside an ordinary class, not inside a generic class. However, it is a generic method. The type variables are inserted after the modifiers (public static, in our case) and before the return type.

You can define generic methods both inside ordinary classes and inside generic classes.

You can place the actual types, enclosed in angle brackets, before the method name:

String[] names = { "John", "Q.", "Public" };

String middle = ArrayAlg.<String>getMiddle(names);

In this case (and indeed in most cases), you can omit the <String> type parameter from the method call. The compiler has enough information to infer the method that you want. It matches the type of names (that is, String[]) against the generic type T[] and deduces that T must be String. That is, you can simply call:

String middle = ArrayAlg.getMiddle(names);

Page 31: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Generic Methods (II) public class Box<T> { private T t; public void add(T t) { this.t = t; } public T get() { return t; } public <U> void inspect(U u){ System.out.println("T: " + t.getClass().getName()); System.out.println("U: " + u.getClass().getName()); } public static void main(String[] args) { Box<Integer> integerBox = new Box<Integer>(); integerBox.add(new Integer(10)); integerBox.inspect("some text"); } }

By passing in different types, the output will change accordingly : T: java.lang.Integer U: java.lang.String

Other example: public static <U> void fillBoxes(U u, List<Box<U>> boxes) { for (Box<U> box : boxes) { box.add(u); } }

Let consider a call of the method. Crayon red = ...; List<Box<Crayon>> crayonBoxes = ...;

Box.<Crayon>fillBoxes(red, crayonBoxes);

More often it can be left out and the compiler will infer

the type that's needed: Box.fillBoxes(red, crayonBoxes); // compiler infers that U is Crayon

Generic methods can be

defined inside ordinary and

generic classes.

When calling a generic method, you need not instantiate the type variables.

Page 32: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Example with Pair public class PairTest1 {

public static void main(String[] args) {

String[] words = { "Mary", "had", "a", "little", "lamb" };

Pair<String> mm = ArrayAlg.minmax(words); System.out.println("min = " + mm.getFirst()); System.out.println("max = " + mm.getSecond()); }

}

class ArrayAlg {

/**

Gets the minimum and maximum of an array of strings.

@param a an array of strings

@return a pair with the min and max value, or null if a is null or empty

*/

public static Pair<String> minmax(String[] a) { if (a == null || a.length == 0) return null;

String min = a[0];

String max = a[0];

for (int i = 1; i < a.length; i++) {

if (min.compareTo(a[i]) > 0) min = a[i];

if (max.compareTo(a[i]) < 0) max = a[i];

}

return new Pair<String>(min, max); }

}

You can think of a generic type method invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you're passing a type argument -here String- to the Pair class itself. Such an invocation of a generic type is known as a parameterized type.

Page 33: Assertions (since Java 1.5) - WordPress.com · An inner class is a class declared inside another type. Nested classes are commonly used for classes that should not be visible elsewhere

Type Parameter Naming Convention

The most commonly used type parameter names are:

E - Element (used extensively by the Java Collections Framework)

K - Key

N - Number

T - Type

V - Value

S,U,V etc. - 2nd, 3rd, 4th types