The Java Assertion

28
The Java Assertion

description

The Java Assertion. Assertion. A Java statement in JDK 1.4 & newer Intent : enables code to test assumptions. E.g., a method that calculates the a particle’s speed, asserts: speed < c (speed of light). - PowerPoint PPT Presentation

Transcript of The Java Assertion

Page 1: The Java Assertion

The Java Assertion

Page 2: The Java Assertion

2

Assertion

• A Java statement in JDK 1.4 & newer

• Intent: enables code to test assumptions. E.g., a method that calculates the a particle’s speed, asserts:

speed < c (speed of light).

• Has a boolean expression whose value is “asserted” to be true when the assertion executes.– If it is false, the system throws an error.

– By evaluating the boolean expression, the assertion confirms assumptions about program behavior.

Increases confidence that the program is error-free.

Page 3: The Java Assertion

3

Assertion …

• Assert: Detecting bugs is quicker when

assertions are included in the code.

• Assertions also document the program,

enhancing maintainability.

Page 4: The Java Assertion

4

Outline

• Introduction

• Using Assertions

• Compiling Files That Use Assertions

• Enabling & Disabling Assertions

Page 5: The Java Assertion

5

Introduction

• The assertion statement has 2 forms:

assert Expression; // Expression1 is boolean

Meaning:

if ( ! Expression )

{

throw AssertionError // no message

}

Page 6: The Java Assertion

6

Introduction …

assert Expression1 : Expression2 ; where: – Expression1 is boolean– Expression2 has a value

Cannot be the returned value of a void method.

Meaning:

if ( ! Expression1 )

{

throw new AssertionError( Expression2 )

}// Expression2’s String value is the message.

Page 7: The Java Assertion

7

The Message

• Should convey details of the assertion failure

• Is not a user-level message

• Need not be understandable in isolation

• Is intended for use with:

– a full stack trace

– the source code.

Page 8: The Java Assertion

8

Introduction …

• The stack trace gives the file/line# of the

failed assertion.

• Use the message form only to add

information that helps diagnose the failure.

E.g., if Expression1 involves a relationship between

variables x & y, use the message form.

E.g.,

assert x < y : “x: “ + x + “, y: “ + y ;

Page 9: The Java Assertion

9

Introduction …

• Assertions can be enabled or disabled when

the program is started.

• Assertions are disabled by default.

• Disabled assertions are equivalent to empty

statements in semantics & performance.

Page 10: The Java Assertion

10

Outline

• Introduction

• Using Assertions

• Compiling Files That Use Assertions

• Enabling & Disabling Assertions

Page 11: The Java Assertion

11

Using Assertions

• Do not use assertions for:

argument checking in public methods.Argument checking is part of the method’s published

specifications (or contract): Specifications are obeyed whether or not assertions are enabled.

• Assert’s expression should have no side-effects.

Exception: assertions can modify state used only from within other assertions (illustrated later).

Page 12: The Java Assertion

12

Internal Invariants

Replaceif ( i % 3 == 0 )

{ ... }

else if ( i % 3 == 1 )

{ ... }

else

{

// We know ( i % 3 == 2 )

...

}

Withif ( i % 3 == 0 )

{ ... }

else if ( i % 3 == 1 )

{ ... }

else

{

assert i % 3 == 2 : i;

...

}

// assert fails for i = -5

Page 13: The Java Assertion

13

Control-Flow InvariantsUse: assert false; // an unreachable point

Replacevoid foo()

{

for (...)

{

if (...) return;

}

// unreachable point

}

With

void foo()

{

for (...)

{

if (...) return;

}

assert false; // unreachable

}

Page 14: The Java Assertion

14

Control-Flow InvariantsUse: assert false; // an unreachable point

• The foregoing only makes sense if reaching a point is possible but erroneous.

• If it is impossible, the compiler handles it.

• If it is possible, you may always throw an exception

Not just when assertions are enabled.

Replace “assert false; ”

with “throw new AssertionError(); ”

Page 15: The Java Assertion

15

Preconditions

• Do not assert method contracts/** * Sets the refresh rate. * @param rate refresh rate, in frames per second. * @throws IllegalArgumentException if rate <= 0 or * rate > MAX_REFRESH_RATE. */ public void setRefreshRate(int rate) { // Enforce specified precondition in public method

if (rate <= 0 || rate > MAX_REFRESH_RATE) throw new IllegalArgumentException("Illegal rate: "

+ rate); setRefreshInterval(1000/rate);

}

Page 16: The Java Assertion

16

Preconditions …

• Assert a nonpublic method's precondition.

• An assertion is appropriate in the following

“helper” method invoked by the previous

method.

Page 17: The Java Assertion

17

/**

* Sets the refresh interval (to a legal frame rate).

* @param interval refresh interval in milliseconds.

*/

private void setRefreshInterval( int interval )

{

// Confirm adherence to precondition in nonpublic method

assert interval > 0 && interval <= 1000/MAX_REFRESH_RATE : interval;

... // Set the refresh interval

}

The assertion can fail if MAX_REFRESH_RATE > 1000.

Page 18: The Java Assertion

18

Lock-Status Precondition

Originalprivate Object[] a;

public synchronized int find(Object key)

{ return find(key, a, 0, a.length);

} // Recursive helper method:

always has lock on thisprivate int find(Object key,

Object[] arr, int start, int len) { ... }

Assert lock status: // Recursive helper method:

always has lock on this.

private int find(Object key, Object[] arr, int start, int len)

{

// lock-status assertion

assert Thread.holdsLock(this);

...

}

Page 19: The Java Assertion

19

Postconditions

Replace

void push( Object o )

{

stack.add( ++top, o );

// top == stack.size();

}

With

void push( Object o )

{

stack.add( ++top, o );

assert top == stack.size() : “top: ”

+ top + “, size: ” + stack.size();

}

Page 20: The Java Assertion

20

Postconditions …

• An assert’s expression may need state.void foo(int[] array) {

// Manipulate array ... // At this point, array contents == itself// prior to manipulation

}Replace the above with the following.

Page 21: The Java Assertion

21

Postconditions …

void foo(final int[] array) { // Inner class that saves state & performs final consistency check class DataCopy {

private int[] arrayCopy; DataCopy() { arrayCopy = ( int[] ) array.clone(); } boolean isConsistent() { return Arrays.equals( array, arrayCopy ); }

} DataCopy copy = null; // Always succeeds; has side effect of saving a copy of array assert ( ( copy = new DataCopy() ) != null ); // copy only if ea... // Manipulate array // Ensure array has same ints in same order as before. assert copy.isConsistent();

}

Page 22: The Java Assertion

22

Class State Invariants

• Class state invariant: an invariant that applies to all instances at the beginning & ending of all methods.E.g., in a balanced tree, a class invariant is that the tree is

balanced.

• Style: combine the expressions that check required constraints into an internal method.

// Returns true if this tree is properly balanced private boolean isBalanced() { ... }

• Assert class invariant just prior to return from public methods & constructors:assert isBalanced();

Page 23: The Java Assertion

23

Outline

• Introduction

• Using Assertions

• Compiling Files That Use Assertions

• Enabling & Disabling Assertions

• Compatibility with Existing Programs

Page 24: The Java Assertion

24

Compiling Files That Use Assertions

To tell javac to accept assertions, use the -

source 1.4 command-line option:

javac -source 1.4 MyClass.java

Page 25: The Java Assertion

25

Outline

• Introduction

• Using Assertions

• Compiling Files That Use Assertions

• Enabling & Disabling Assertions

Page 26: The Java Assertion

26

Enabling & Disabling Assertions

• By default, assertions are disabled. • Enable assertions, using the -ea, switch. • Disable assertions, using the -da, switch. • Specify granularity as the switch argument:

• no arguments    Enables/disables assertions in all classes except system classes.

• packageName...    Enables/disables assertions in the package & any subpackages.

• ...   Enables/disables assertions in the unnamed package in the current working directory.

• className   Enables/disables assertions in the named class.

Page 27: The Java Assertion

27

Enabling & Disabling Assertions

• To run BatTutor, with assertions enabled in only package com.wombat.fruitbat & its subpackages:

java -ea:com.wombat.fruitbat... BatTutor

• To run BatTutor with assertions: – enabled in package com.wombat.fruitbat – disabled in class

com.wombat.fruitbat.Brickbat: java -ea:com.wombat.fruitbat... -

da:com.wombat.fruitbat.Brickbat BatTutor

Page 28: The Java Assertion

28

Enabling & Disabling Assertions

To (en/dis)able system class assertions, use:

-esa

-dsa

To run BatTutor with assertions:

• enabled in system classes,

• enabled in the com.wombat.fruitbat package & its

subpackages:

java -esa -ea:com.wombat.fruitbat... BatTutor