Download presentation
Presentation is loading. Please wait.
1
Exam 2 Review
2
Exam 2 Exam 2 on Thursday, March 29th
Closed book, closed computer, closed phone You are allowed two “cheat” pages Either a standard 8.5x11-sized sheet filled on both sides or two standard sheets filled on one side each Type or write by hand (which I recommend)
3
Topics Exceptions Preconditions vs. exceptions, throwing and catching, propagation down the call stack, exceptions vs. special values, checked vs. unchecked exceptions Spring 18 CSCI 2600, K. Kuzmin, A Milanova
4
Preconditions vs. Exceptions
In certain cases, preconditions are a valid choice When checking is expensive. E.g., binarySearch In private methods, usually used in local context Whenever possible, remove preconditions from public methods and specify behavior Usually, this entails throwing an Exception Stronger spec, easier to use by client Spring 18 CSCI 2600, K. Kuzmin, A Milanova
5
Throwing and Catching Java maintains a call stack of methods that are currently executing When an exception is thrown, control transfers to the nearest method with a matching catch block If none found, top-level handler Exceptions allow for non-local error handling A method far down the call stack can handle a deep error! . Is non-local handling good or bad? BAD: it can be hard to find where the error occurred. Suppose that readFile violated readLine’s precondition. readLine didn’t check, just passed erroneous input down and decodeChar was the first to “suffer” from the wrong input, in the sense that decodeChar was the first to throw an Exception. The Exception deeply up the call stack, at decodeChar would be hard to trace to the error in readLine. Better: readLine specified the Exception and threw the Exception when erroneous input was passed. readFile is likely at fault, programmer will trace and fix. decodeChar readChar readLine readFile main Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Michael Ernst)
6
Informing the Client of a Problem
Special value null – Map.get(x) -1 – List.indexOf(x) NaN – sqrt of negative number Problems with using special value Hard to distinguish from real values Error-prone: programmer forgets to check result? The value is illegal and will cause problems later Ugly Exceptions are generally a better way to inform of a problem
7
Two Distinct Uses of Exceptions
Failures Unexpected by your code Usually unrecoverable. If condition is left unchecked, exception propagates down the stack Special results Expected by your code Unknowable for the client of your code Always check and handle locally. Take special action and continue computing Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Michael Ernst)
8
Java Exceptions: Checked vs. Unchecked Exceptions
Checked exceptions. For special results Library: must declare in signature Client: must either catch or declare in signature It is guaranteed there is a dynamically enclosing catch Unchecked exceptions. For failures Library: no need to declare Client: no need to catch RuntimeException and Error FileNotFound Throwable Exception Error Checked Exception Runtime Exception Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Michael Ernst)
9
Topics Testing Black box heuristics: equivalence partitioning, boundary value analysis, white box heuristics: control-flow graph (CFG), statement coverage, branch coverage, def-use coverage. Spring 18 CSCI 2600, K. Kuzmin, A Milanova
10
Testing Strategies Test case: specifies Black box testing:
Inputs + pre-test state of the software Expected result (outputs and post-test state) Black box testing: We ignore the code of the program. We look at the specification (roughly, given some input, was the produced output correct according to the spec?) Choose inputs without looking at the code White box (clear box, glass box) testing: We use knowledge of the code of the program (roughly, we write tests to “cover” internal paths) Choose inputs with knowledge of implementation Spring 18 CSCI 2600, K. Kuzmin, A Milanova
11
Equivalence Partitioning
Partition the input and/or output domains into equivalence classes Write tests with inputs from different equivalence classes in the input domain Write tests that produce outputs in different equivalence classes in the output domain Spring 18 CSCI 2600, K. Kuzmin, A Milanova
12
Boundary Value Analysis
Choose test inputs at the edges of input equivalence classes Choose test inputs that produce outputs at the edges of output equivalence classes Other boundary cases Arithmetic: zero, overflow Objects: null, circular list, aliasing
13
Control-flow Graph (CFG)
Assignment x=y+z => node in CFG: If-then-else if (b) S1 else S2 => x=y+z b (b) is a predicate node True False CFG for S1 CFG for S2 end-if Spring 18 CSCI 2600, K. Kuzmin, A Milanova
14
Control-flow Graph (CFG)
Loop while (b) S => (b) is a predicate node b True False CFG for S Spring 18 CSCI 2600, K. Kuzmin, A Milanova
15
Coverage Statement coverage: Write a test suite that covers all statements, or in other words, all nodes in the CFG Branch coverage: write a test suite that covers all branch edges at predicate nodes The True and False edge at if-then-else The two branch edges corresponding to the condition of a loop All alternatives in a SWITCH statement Spring 18 CSCI 2600, K. Kuzmin, A Milanova
16
White Box Testing: Dataflow-based Testing
A definition (def) of x is x at the left-hand-side E.g., x = y+z, x = x+1, x = foo(y) A use of x is when x is at the right-hand side E.g., z = x+y, x = x+y, x>y, z = foo(x) A def-use pair of x is a pair of nodes, k and n in the CFG, s.t. k is a def of x, n is a use of x, and there is a path from k to n free of definition of x k: x=… x = … n: …= x…
17
White Box Testing: Dataflow-based Testing
Dataflow-based testing targets: write tests that cover paths between def-use pairs Intuition: If code computed a wrong value at a def of x, the more uses of this def of x we “cover”, the higher the possibility that we’ll expose the error If code had erroneous use of x, the more def-use pairs we “cover”, the higher the possibility that we’ll expose the error at the use of x
18
A Buggy gcd // requires a,b > 0
static int gcd(int a, int b) { int x=a; int y=b; while (x != y) { if (x > y) { x = x – 2y; } else { y = y – x; } } return x; } Let’s test with gcd(15,6) and gcd(4,8). What’s the statement coverage? Branch? We have 100% statement coverage and 100% branch coverage. a = a-2b did a wrong computation. Our test cases tested def-use pairs: (def: a = a – 2b, use: b = b - a). But they didn’t cover (a = a-2b, a=a-2b), (b=b-a, a=a-2b), (b=b-a,b=b-a).
19
CFG for Buggy GCD Def-use pairs for x: (node 1, node 2) (4,2)
(1,3) (4,3) (1,4) (4,4) (1,5) (4,5) (1,7) (4,7) Back edge 1.x=a; y=b; 2. x!=y False True 3. x>y Def-use coverage targets: cover paths connecting def-use pairs False True 4.x=x-2y; 5.y=y-x; 6. 7.res=x; “Merge” node
20
Def-use Coverage Targets
The All-defs coverage target: for every def x, cover at least one path (free of definition of x), to at least one use x The All-uses coverage target: for every def-use pair of x, cover at least one path (free of definition of x) from the def x to the use x The All-du-paths coverage target: for every def-use pair of x, cover every path (free of definition of x) from the def x to the use x Spring 18 CSCI 2600, K. Kuzmin, A Milanova
21
Topics Subtyping vs. subclassing
Subtype polymorphism, true subtypes and the LSP, specification strength and comparing specifications (again), Function sybtyping, Java subtyping (overriding and overloading) Spring 18 CSCI 2600, K. Kuzmin, A Milanova
22
Subtype Polymorphism Subtype polymorphism – the ability to use a subclass where a superclass is expected Thus, dynamic method binding class A { void m() { … } } class B extends A { void m() { … } } class C extends A { void m() { … } } Client: A a; … a.m(); // Call a.m() can bind to any of A.m, B.m or C.m at runtime! Subtype polymorphism is a language feature --- essential object-oriented language feature Java subtype: B extends A or B implements I A Java subtype is not necessarily a true subtype! override A.m What is polymorphism? In programming languages, (very roughly!) polymorphism refers to the fact that the same variable can hold entities of different types and this one variable can be used uniformly through a common interface, regardless of actual type. Another important notion (in addition to subtype polymorphism) is parametric polymorphism, which you know of as “templates” in C++, or generics in Java.
23
Benefits of Subtype Polymorphism
“Science” of software design teaches Design Patterns Design patterns promote design for extensibility and reuse Nearly all design patterns make use of subtype polymorphism Spring 18 CSCI 2600, K. Kuzmin, A Milanova
24
Subtypes are Substitutable
Subtypes are substitutable for supertypes Instances of subtype won’t surprise client by expecting more than the supertype Instances of subtypes won’t surprise client by failing to satisfy supertype postcondition B is a true subtype (or “behavioral” subtype) of A if B has stronger specification than A Not the same as Java subtype! Java subtypes that are not true subtypes are confusing and dangerous
25
Liskov Substitution Principle (LSP)
Due to Barbara Liskov, Turing Award 2008 LSP: A subclass B should be substitutable for its superclass A. I.e., B is a true subtype of A To ensure that B is substitutable: B does not remove methods from A For each B.m that “replaces” A.m, B.m’s specification is stronger than A.m’s specification Client: A a; … a.m(int x, int y); Call a.m can bind to B’s m. B’s m should not surprise client This is why we needed to reason about which specification is stronger! Most of the time though you won’t need formal reasoning, you can do by-hand reasoning!
26
Function Subtyping In programming languages function subtyping deals with substitutability of functions Question: under what conditions on the parameter and return types A,B,C and D, is function A f(B) substitutable for C f(D) Reasons at the level of the type signature Rule: A f(B) is a function subtype of C f(D) if A is a subtype of C and B is a supertype of D Guarantees substitutability Spring 18 CSCI 2600, K. Kuzmin, A Milanova
27
Type Signature of Substituting Method is Stronger
Method parameters (inputs): Parameter types of A.m may be replaced by supertypes in subclass B.m. ”contravariance” E.g., A.m(String p) and B.m(Object p) B.m places no extra requirements on the client! E.g., client: A a; … a.m(q). Client knows to provide q a String. Thus, client code will work fine with B.m(Object p), which asks for less: an Object, and clearly, every String is an Object Java does not allow change of parameter types in an overriding method. More on Java overriding shortly B Think of parameters and return as part of the method specification (not including behavior). As we discussed some time ago.
28
Type Signature of Substituting Method is Stronger
Method returns (results): Return type of A.m may be replaced by subype in subclass B.m. “covariance” E.g., Object A.m() and String B.m() B.m does not violate expectations of the client! E.g., client: A a; … Object o = a.m(). Client expects an Object. Thus, String will work fine No new exceptions. Existing exceptions can be replaced by subtypes Java does allow a subtype return type in an overriding method! B Think of return type as part of the postcondition of the spec.
29
Reasoning about Specs Function subtyping reasons with type signatures
Remember, type signature is a specification Precondition: requires arguments of given type Postcondition: promises result of given type Compiler checks function subtyping Specifications add reasoning about behavior and effects Precondition: stated by requires clause Postcondition: stated by modifies, effects, returns and throws clauses
30
Reason about Specs “Behavioral” subtyping generalizes function subtyping B.m is a true subtype (behavioral subtype) of A.m B.m has weaker precondition than A.m Generalizes “B.m’s parameter is a supertype of A.m’s parameter” premise of function subtyping rule Contravariance B.m has stronger postcondition than A.m Generalizes “B.m’s return is a subtype of A.m’s return” Covariance These 2 conditions guarantee B.m’s spec is stronger than A.m’s spec, and B.m is substitutable for A.m
31
Java Subtypes Java types are defined by classes, interfaces, primitives Java subtyping stems from declarations B extends A B implements A In a Java subtype, a “substituting” method is an overriding method Has same parameter types Has compatible (same or subtype) return type Has no additional declared exceptions Overriding Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Mike Ernst)
32
Java Subtypes: Overloading vs. Overriding
A method family contains multiple implementations of same name + parameter types subsignature (no return type) Which method family gets called is determined at compile time based on static types of receiver and parameters E.g., family put(Object key, Object value) or family put(String key, String value) Which implementation from method family runs, is determined at runtime based on type of the receiver Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slides by Mike Ernst)
33
Exercise class Y extends X { … } class A { X m(Object o) { … } } class B extends A { X m(Z z) { … } class C extends B { Y m(Z z) { … } A a = new B(); Object o = new Object(); // Which m is called? X x = a.m(o); A a = new C(); Object o = new Z(); What are the method families? Spring 18 CSCI 2600, K. Kuzmin, A Milanova
34
Exercise class Y extends X { … } class W extends Z { … } class A { X m(Z z) { … } } class B extends A { X m(W w) { … } class C extends B { Y m(W w) { … } A a = new B(); W w = new W(); // Which m is called? X x = a.m(w); B b = new C(); X x = b.m(w); Spring 18 CSCI 2600, K. Kuzmin, A Milanova
35
Topics Equality Properties of equality, reference vs. value equality, equality and inheritance, equals and hashCode, equality and mutation Spring 18 CSCI 2600, K. Kuzmin, A Milanova
36
Equality: == and equals()
In Java, == tests for reference equality. This is the strongest form of equality Usually we need a weaker form of equality, value equality In our Point example, we want x to be “equal” to y because the x and y objects hold the same value Need to override Object.equals y z x y 2 5 2 5
37
Properties of Equality
Equality is an equivalence relation Reflexive a.equals(a) Symmetric a.equals(b) b.equals(a) Transitive a.equals(b) ∧ b.equals(c) a.equals(c) Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Michael Ernst)
38
Equality and Inheritance
Let B extend A “Natural” definition of B.equals(Object) may lose symmetry “Fix” may render equals()non-transitive One can avoid these issues by defining equality for exact classes (has pitfalls too) if (!o.getClass().equals(getClass())) return false; Spring 18 CSCI 2600, K. Kuzmin, A Milanova
39
equals and hashCode hashCode computes an index for the object (to be used in hashtables) Javadoc for Object.hashCode(): “Returns a hash code value of the object. This method is supported for the benefit of hashtables such as those provided by HashMap.” Self-consistent: o.hashCode() == o.hashCode() … as long as o does not change between the calls Consistent with equals() method: a.equals(b) => a.hashCode() == b.hashCode()
40
Equality, mutation and time
If two objects are equal now, will they always be equal? In mathematics, the answer is “yes” In Java, the answer is “you chose” The Object spec does not specify this For immutable objects Abstract value never changes, equality is eternal For mutable objects We can either compare abstract values now, or be eternal (can’t have both since value can change) Spring 18 CSCI 2600, K. Kuzmin, A Milanova (slide by Michael Ernst)
41
Equality and Mutation Client may violate rep invariant of a Set container (rep invariant: there are no duplicates in set) by mutating elements after insertion Set<Date> s = new HashSet<Date>(); Date d1 = new Date(0); Date d2 = new Date(1); s.add(d1); s.add(d2); d2.setTime(0); // mutation after d2 already in the Set! for (Date d : s) { System.out.println(d); }
42
Topics Parametric Polymorphism
Declaring and instantiating generics, Bounded types, Wildcards, Type erasure, Arrays Spring 18 CSCI 2600, K. Kuzmin, A Milanova
43
Polymorphism Subtype polymorphism Parametric polymorphism
Code can use a subclass B where a superclass A is expected Standard in object-oriented languages Parametric polymorphism Code takes a type as a parameter Implicit parametric polymorphism Explicit parametric polymorphism If you talk to someone who programs in OO languages (C++, Java, etc.), when they say “polymorphism” they most likely mean subtype polymorphism. Spring 18 CSCI 2600, K. Kuzmin, A Milanova
44
Using Java Generics List<AType> list = new ArrayList<AType>(); AType is the type argument. We instantiated generic (templated) class ArrayList with concrete type argument AType List<String> names = new ArrayList<String>(); names.add(“Ana”); names.add(“Katarina”); String s = names.get(0); // what happens here? Point p = names.get(0); // what happens here? Point p = (Point) names.get(0); // what happens? Point p = names.get(0); // compile-time error Point p = (Point) names.get(0); // compile-time error again Spring 18 CSCI 2600, K. Kuzmin, A Milanova (modified from an example by Michael Ernst)
45
Defining a Generic Class
Declaration of type parameter class MySet<T> { // rep invariant: non-null, // contains no duplicates List<T> theRep; T lastLookedUp; } Other terms for “generic”: parameterized or templated. In C++ you’ll use the phrase template<class V> Use of type parameter Spring 18 CSCI 2600, K. Kuzmin, A Milanova (example by Michael Ernst)
46
Bounded Type Parameters
<Type extends SuperType> An upper bound, type argument can be SuperType or any of its subtypes <Type super SubType> A lower bound, type argument can be SubType or any of its supertypes Spring 18 CSCI 2600, K. Kuzmin, A Milanova (modified from slide by Michael Ernst)
47
Exercise Given this hierarchy with X, Y and Z:
What are valid instantiations of generics class A<T extends X> { … } ? class A<T extends Z> { … } ? class A<T super Z> { … } ? class A<T super X> { … } ? Y Z Spring 18 CSCI 2600, K. Kuzmin, A Milanova
48
More Bounded Type Examples
<T extends Comparable<T>> T max(Collection<T> c); <T> void copy(List<T2 super T> dst, List<T3 extends T> src); (actually, must use wildcard ? --- more on this later: <T> void copy(List<? super T> dst, List<? extends T> src); ) <T extends Comparable<T2 super T>> void sort(List<T> list) (same, must use ? with super: <? super T>) What is the meaning of these declarations? First one is trivial. Second one is interesting: T2 super T means T2 is a supertype of T. T3 extends T means that T3 is a subtype of T. Thus, T3 is a subtype of T2! This makes sense: the destination list must be able to store all elements stored in the source list. Examples: List<Number> l1; List<String> l2; copy(l1,l2); // compile-time error. Informally, we cannot store Strings into a list of Numbers!. Formally, there does not exist T, such that <Number super T> and <String extends T>! Another example: List<String> l1; List<Object> l2; copy(l1,l2); // compile-time error. We cannot store Objects into a list of Strings. (In other words: we cannot store Objects into an array that expectss Strings). Formally, Object is not a subtype of String. Another example. List<Object> l1; copy(l1,l2); // OK. Third example: sort any list that can be compared to same type or to a broader (more general, super) type. Spring 18 CSCI 2600, K. Kuzmin, A Milanova (modified from a slide by Michael Ernst)
49
Thus, List<Number> and
What is the Subtyping Relationship Between List<Number> and List<Integer> Java subtyping is invariant with respect to generics: if A ≠ B, then C<A> has no subtyping relationship with C<B> Thus, List<Number> and List<Integer> are unrelated through subtyping! List<Number> List<Integer>
50
Invariance is Restrictive (Because it Disallows Subtyping!)
Not good. Can’t have Set<Number> s; List<Number> l; s.addAll(l); // List & Set unrelated Java solution: wildcards interface Set<E> { // Ads all elements in c to this set // if they are not already present. void addAll(Set<E> c); void addAll(Collection<E> c); void addAll(Collection<? extends E> c); <T extends E> void addAll(Collection<T> c); } Not good either. Can’t have Set<Number> s; List<Integer> l; s.addAll(l); This is because of invariance: List<Integer> is a subtype of Collection<Integer> but Collection<Integer> is not a subtype of Collection<Number>! Solution: wildcards. ? Is the wildcard.
51
Java Wildcards A wildcard is essentially an anonymous type variable
Use ? if you’d use a type variable exactly once ? appears at the instantiation site of the generic (also called use site) As opposed to declaration site (also called definition site: where type parameter is declared) Purpose of the wildcard is to make a library more flexible and easier to use by allowing limited subtyping
52
Legal Operations on Wildcards
Object o; Number n; Integer i; PositiveInteger p; List<? extends Integer> lei; First, which of these is legal? lei = new ArrayList<Object>(); lei = new ArrayList<Number>(); lei = new ArrayList<Integer>(); lei = new ArrayList<PositiveInteger>(); lei = new ArrayList<NegativeInteger>(); Which of these is legal? lei.add(o); lei.add(n); lei.add(i); lei.add(p); lei.add(null); o = lei.get(0); n = lei.get(0); i = lei.get(0); p = lei.get(0); The purpose of the wildcard is to allow for subtyping! The type declaration List<? extends Integer> means that very List<Type> such that Type extends Integer, is a subtype of List<? extends Integer> (and thus,s can be used where List<? extends Integer> is expected) Here: covariant subtyping must be restricted to immutable lists. lei can be read, but can’t be written into (because writing is not safe). Spring 18 CSCI 2600, K. Kuzmin, A Milanova (slide due to Michael Ernst)
53
Legal Operations on Wildcards
Which of these is legal? lsi.add(o); lsi.add(n); lsi.add(i); lsi.add(p); lsi.add(null); o = lsi.get(0); n = lsi.get(0); i = lsi.get(0); p = lsi.get(0); Object o; Number n; Integer i; PositiveInteger p; List<? super Integer> lsi; First, which of these is legal? lsi = new ArrayList<Object>(); lsi = new ArrayList<Number>(); lsi = new ArrayList<Integer>(); lsi = new ArrayList<PositiveInteger>(); And here: contravariant subtyping must be restricted to (mainly) write-only lists. lsi can be written, but reading is problematic (basically, we can only read into object variables). So if we used it for reading, we’ll have to typecast at the get site. Spring 18 CSCI 2600, K. Kuzmin, A Milanova (slide due to Michael Ernst)
54
How to Use Wildcards Use <? extends T> when you get (read) values from a producer Use <? super T> when you add (write) values into a consumer E.g.: <T> void copy(List<? super T> dst, List<? extends T> src) PECS: Producer Extends, Consumer Super Use neither, just <T>, if both add and get Spring 18 CSCI 2600, K. Kuzmin, A Milanova (based on slide by Michael Ernst)
55
Arrays and Subtyping Integer is subtype of Number
Is Integer[] a subtype of Number[] Use our subtyping rules to find out (Just like with List<Integer> and List<Number>) Again, the answer is NO! Different answer in Java: in Java Integer[] is a Java subtype Number[]! The Java subtype is not a true subtype! Known as “problem with Java’s covariant arrays” Number[] ? Integer[] Arrays are very similar to generics. Array is composite type, enclosing a type.
56
Integer[] is a Java subtype of Number[]
Number n; ia = na; //what Number[] na; // happens here? Integer i; Double d = 3.14; Integer[] ia; na = ia; //OK! na[0] = n; na[2] = d; na[1] = i; i = ia[2]; //what n = na[0]; // happens here? i = na[1]; //what happens? ia[0] = n; //what happens? ia[1] = i; n = ia[0]; i = ia[1];
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.