12. common errors, a few puzzles. © o. nierstrasz p2 — common errors, a few puzzles 12.2 common...

25
12. Common Errors, a few Puzzles

Upload: noelle-tansill

Post on 14-Dec-2015

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

12. Common Errors, a few Puzzles

Page 2: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.2

Common Errors, a few Puzzles

Sources> Cay Horstmann, Computing Concepts with Java

Essentials, Wiley, 1998> The Java Report, April 1999

Page 3: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.3

Roadmap

> Common errors …— Typical programming traps

> A few Java puzzles ...— The darker side of Java

Page 4: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.4

Roadmap

> Common errors …— Typical programming traps

> A few Java puzzles ...— The darker side of Java

Page 5: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.5

Trap 1

What does this print?

25.0 Don’t assume that floating point numbers are exact representations of mathematical values!

double f = 2e15 + 0.13;double g = 2e15 + 0.02;

println(100*(f-g));

Page 6: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.6

static void test(String name, boolean bool) {println(name + ": " + (bool?"true":"false"));

}

Trap 2

When are two Strings equal?

== tests object identity;equals() tests object equality

String s1 = new String("This is a string");String s2 = new String("This is a string");test("String==", s1 == s2);test("String.equals", s1.equals(s2));

String==: falseString.equals: true

Page 7: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.7

Trap 3

When are two Objects equal?

object==: falseobject.equals: false

The default implementation of equals() is ==, and should normally be overwritten

Object x = new Object();Object y = new Object();test("object==", x == y);test("object.equals", x.equals(y));

Page 8: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.8

Trap 4

When are two Strings equal?

String==: trueString.equals: true

Literal strings with the same content refer to the same object!Always use equals() or compareTo() to compare strings.

String s3 = "This is a string";String s4 = "This is a string";test("String==", s3 == s4);test("String.equals", s3.equals(s4));

Page 9: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.9

Trap 5

Is “now” really before “later”?

see you now

Date later = new Date(now.getTime());

Explicitly create a clone if you need one:

Calendar now = Calendar.getInstance();Calendar later = now;later.set(Calendar.HOUR_OF_DAY, 1 + now.get(Calendar.HOUR_OF_DAY));if (now.before(later)) {

println("see you later");} else {

println("see you now");}

Page 10: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.10

Trap 6

nothing0 is even1 is negative

static void checkEven(int n) {boolean result = true;if (n>=0)

if ((n%2) == 0)println(n + " is even");

elseprintln(n + " is negative");

}

What is printed when we run these checks?

checkEven(-1);checkEven(0);checkEven(1);

Always use braces to group nested if { } else { } statements!

if (n>=0) {if ((n%2) == 0) {println(n + " is even");

} else {println(n + " is negative");

}}

Page 11: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.11

Trap 7

The binomial coefficient is

Is this a correct implementation?

binomial(7,3) = 21 35

To avoid off-by-1 errors:1.Count the iterations — do

we always do k multiplications? (no)

2.Check boundary conditions — do we start with n/1 and finish with (n-k+1)/k? (no)

Off-by-1 errors are among the most common mistakes in implementing algorithms.

static int binomial(int n, int k) {int bc = 1;for (int i=1; i<k; i++) {

bc = bc * (n+1-i) / i;}return bc;

}

Page 12: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.12

Trap 8

For which values does this function work correctly?

brokenFactorial(0) = 1brokenFactorial(5) = 120brokenFactorial(-1) = ... (doesn’t terminate)

Always use an inequality test to terminate a loop.

static int brokenFactorial(int n) {int result=1;for (int i=0; i!=n; i++ ) {

result = result*(i+1);}return result;

}

Page 13: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.13

Some other common errors

Magic numbers> Never use magic numbers; declare constants instead.Forgetting to set a variable in some branch> If you have non-trivial control flow to set a variable, make sure it

starts off with a reasonable default value.Underestimating size of data sets> Don’t write programs with arbitrary built-in limits (like line-length);

they will break when you least expect it.Leaking encapsulation> Never return a private instance variable! (return a clone instead)

Bugs are always matter of invalid assumptions not holding

Page 14: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.14

Roadmap

> Common errors …— Typical programming traps

> A few Java puzzles ...— The darker side of Java

Page 15: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.15

Puzzle 1

A.p()Private methods are statically bound.

A b = new B();b.m();

class A {public void m() { this.p(); }private void p() { println("A.p()"); }

}class B extends A {

private void p() { println("B.p()"); }}

Are private methods inherited?

Which is called? A.p() or B.p()?

Page 16: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.16

Static and Dynamic Types

Consider:

The static type of variable a is A — i.e., the statically declared class to which it belongs.The static type never changes.

The dynamic type of a is B — i.e., the class of the object currently bound to a.The dynamic type may change throughout the program.

Now the dynamic type is also A!

A a = new B();

a = new A();

Page 17: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.17

Puzzle 2 (part I)

m(A,A)m(A,B)m(B,A)m(B,B)

The static type of arguments is always used to resolve overloaded method calls.

class A { }class B extends A { }void m(A a1, A a2) { println("m(A,A)"); };void m(A a1, B b1) { println("m(A,B)"); };void m(B b1, A a1) { println("m(B,A)"); };void m(B b1, B b2) { println("m(B,B)"); };B b = new B(); A a = b;

How are overloaded method calls resolved?

m(a, a);m(a, b);m(b, a);m(b, b);

Which is considered: the static or dynamic argument type?

Page 18: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.18

Puzzle 2 (part II)

What happens if we comment out:

Will the examples still compile?If so, which methods are called?

m(a,a) won’t compilem(b,b) won’t compilePrints:

m(A,A)

m(A,A)

m(B,A)

m(B,B)

m(A,A)?m(B,B)?m(A,B)?

Page 19: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.19

Puzzle 3

How do static and dynamic types interact?

A.m(A)A.m(A)A.m(A)B.m(B)

Static types determine which message is sent.Dynamic types determine which method is called.

a.m(a);a.m(b);b.m(a);b.m(b);

class A {void m(A a) { println("A.m(A)"); }

}class B extends A {

void m(B b) { println("B.m(B)"); } }B b = new B(); A a = b;

In which cases will B.m(B) be called?

Page 20: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.20

Puzzle 4 (part I)

C.i = 0C.j = 0C.k = 0C.l = 0

First, default values are assigned ... then constructors are evaluated.

How do default values and constructors interact?class C {

int i = 100, j = 100, k = init(), l = 0;C() { i = 0; k = 0; }int init() { j = 0; l = 100; return 100; }

}

What gets printed? 0 or 100?

C c = new C();println("C.i = " + c.i);println("C.j = " + c.j);println("C.k = " + c.k);println("C.l = " + c.l);

Page 21: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.21

Puzzle 4 (part II)

B.i = 0B.j = 0

First all super initialization is executed, then the subclass initialization

abstract class A {int j = 100;A() { init(100); j = 200; }abstract void init(int value);

}class B extends A {

int i = 0, j = 0;B() { super(); }void init(int value) { i = value; }

}

B b = new B();println("B.i = " + b.i);println("B.j = " + b.j);

What gets printed? 0, 100 or 200?

Page 22: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.22

Puzzle 5

The finally clause always takes precedence!3

Does try or finally return?

class A {int m() {

try { return 1; }catch (Exception err) { return 2; }finally { return 3; }

}}

Prints 1, 2, or 3?

A a = new A();println(a.m());

Page 23: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.23

What you should know!

When can you trust floating-point arithmetic? To which “if” does an “else” belong in a nested if

statement? How can you avoid off-by-1 errors? Why should you never use equality tests to terminate

loops? Are private methods inherited? What are the static and dynamic types of variables? How are they used to dispatch overloaded methods?

Page 24: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.24

Can you answer these questions?

When is method dispatching ambiguous? Is it better to use default values or constructors to

initialize variables? If both a try clause and its finally clause throw an

exception, which exception is really thrown?

Page 25: 12. Common Errors, a few Puzzles. © O. Nierstrasz P2 — Common Errors, a few Puzzles 12.2 Common Errors, a few Puzzles Sources  Cay Horstmann, Computing

© O. Nierstrasz

P2 — Common Errors, a few Puzzles

12.25

License

> http://creativecommons.org/licenses/by-sa/2.5/

Attribution-ShareAlike 2.5You are free:• to copy, distribute, display, and perform the work• to make derivative works• to make commercial use of the work

Under the following conditions:

Attribution. You must attribute the work in the manner specified by the author or licensor.

Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one.

• For any reuse or distribution, you must make clear to others the license terms of this work.• Any of these conditions can be waived if you get permission from the copyright holder.

Your fair use and other rights are in no way affected by the above.