Effective Java: Methods Common to All Objects SWE 619: Fall 2008 Paul Ammann.

Slides:



Advertisements
Similar presentations
Identity and Equality Based on material by Michael Ernst, University of Washington.
Advertisements

Singleton vs utility class  at first glance, the singleton pattern does not seem to offer any advantages to using a utility class  i.e., a utility class.
Mutability SWE 332 Fall 2011 Paul Ammann. SWE 3322 Data Abstraction Operation Categories Creators Create objects of a data abstraction Producers Create.
Programo Issues Cora Pérez Ariza ~ DECSAI ~ UGR Granada, January 28 th & 29 th, 2009.
Effective Java, Chapter 3: Methods Common to All Objects.
1 Class Design CS 3331 Fall Outline  Organizing classes  Design guidelines  Canonical forms of classes equals method hashCode method.
Effective Java, Chapter 3: Methods Common to All Objects Paul Ammann.
== equals ? CSE 331 SOFTWARE DESIGN & IMPLEMENTATION EQUALITY Autumn 2011.
Searching. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
Searching and Sorting I 1 Searching and Sorting 1.
CS2200 Software Development Lecture: Object class A. O’Riordan, 2008.
ICS201 Lecture 20 : Searching King Fahd University of Petroleum & Minerals College of Computer Science & Engineering Information & Computer Science Department.
Java 1.5 & Effective Java Fawzi Emad Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
1 Java Object Model Part 2: the Object class. 2 Object class Superclass for all Java classes Any class without explicit extends clause is a direct subclass.
Searching. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
Searching. Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an element in it static.
Comparing Objects in Java. The == operator When you define an object, for instance Person p = new Person("John", 23); we talk about p as if its value.
Searching Also: Logarithms. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an.
CS2110: SW Development Methods Textbook readings: MSD, Chapter 8 (Sect. 8.1 and 8.2) But we won’t implement our own, so study the section on Java’s Map.
Equality CSE 331 University of Washington. Object equality A simple idea - we have intuitions about equality: - Two objects are equal if they have the.
Searching Also: Logarithms. 2 Searching an array of integers If an array is not sorted, there is no better algorithm than linear search for finding an.
Computer Science and Engineering College of Engineering The Ohio State University Lot More Inheritance and Intro to Design Patterns Lecture 12.
Implications of Inheritance COMP204, Bernhard Pfahringer.
Object-oriented Programming in Java. What is OOP?  The goal is (subtype) polymorphism  Achieved by Classes (user-defined types) Classes (user-defined.
Puzzle 3 1  Write the class Enigma, which extends Object, so that the following program prints false: public class Conundrum { public static void main(String[]
Non-static classes Part 2 1. Methods  like constructors, all non-static methods have an implicit parameter named this  for methods, this refers to the.
Not overriding equals  what happens if you do not override equals for a value type class?  all of the Java collections will fail in confusing ways 1.
Hello.java Program Output 1 public class Hello { 2 public static void main( String [] args ) 3 { 4 System.out.println( “Hello!" ); 5 } // end method main.
Effective C#, Chapter 1: C# Language Elements Last Updated: Fall 2011.
Checking Equality of Reference Variables. Arrays and objects are both “reference” types n They are allocated a chunk of memory in the address space n.
332 Final Review Last updated Fall 2013 Professor Ammann.
Chapter 3 Inheritance and Polymorphism Goals: 1.Superclasses and subclasses 2.Inheritance Hierarchy 3.Polymorphism 4.Type Compatibility 5.Abstract Classes.
CSE 331 Software Design & Implementation Hal Perkins Winter 2013 ==, equals(), and all that (Slides by David Notkin and Mike Ernst) 1.
HashCode() 1  if you override equals() you must override hashCode()  otherwise, the hashed containers won't work properly  recall that we did not override.
Chapter 14 Abstract Classes and Interfaces. Abstract Classes An abstract class extracts common features and functionality of a family of objects An abstract.
Inheritance (Part 5) Odds and ends 1. Static Methods and Inheritance  there is a significant difference between calling a static method and calling a.
Symbol Tables From “Algorithms” (4 th Ed.) by R. Sedgewick and K. Wayne.
Polymorphism Liskov 8. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism.
Java Type System and Object Model Horstmann ch , 7.7.
SOEN 343 Software Design Section H Fall 2006 Dr Greg Butler
Data Abstraction SWE 619 Software Construction Last Modified, Spring 2009 Paul Ammann.
1 Class Design CS 3331 Sec 6.1 & 6.3 of [Jia03]. 2 Outline  Organizing classes  Design guidelines  Canonical forms of classes equals method hashCode.
Inheritance Type/Subtype Relationship. Inheritance Idea: An object B of one type, termed child class, inherits from another object A of another type,
The Prototype Pattern (Creational) ©SoftMoore ConsultingSlide 1.
CS 151: Object-Oriented Design November 12 Class Meeting Department of Computer Science San Jose State University Fall 2013 Instructor: Ron Mak
Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display. Relations.
Polymorphism SWE 619. Outline equals() Revisiting Liskov’s mutable vs. not rule Polymorphism Uniform methods for different types “easy” polymorphism Element.
(c) University of Washington06-1 CSC 143 Java Inheritance Tidbits.
Iteration Abstraction SWE Software Construction Fall 2009.
CSC142 NN 1 CSC 142 Overriding methods from the Object class: equals, toString.
Reference Types CSE301 University of Sunderland Harry R Erwin, PhD.
1 CSE 331 The Object class; Object equality and the equals method slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R.
The Object class Object package java.lang Object clone equals hashCode toString aCopy toThis hash string ! yesOrNo.
619 Final Review Last updated Fall 2011 Paul Ammann.
1 clone() Defined in Object Creates an identical copy –Copies pointers to fields (does not copy fields of fields) –Makes a shallow copy if the object’s.
Searching.
Object-oriented Programming in Java
Non-static classes.
CSE 331 Software Design and Implementation
Testing, cont., Equality and Identity
Fall 2018 CISC124 12/3/2018 CISC124 or talk to your grader with questions about assignment grading. Fall 2018 CISC124 - Prof. McLeod Prof. Alan McLeod.
619 Final Review Last updated Spring 2010 © : Paul Ammann.
619 Final Review Fall 2017 Professor Ammann.
Effective Java, Chapter 3, 3rd Edition: Methods Common to All Objects
Searching.
CS/ENGRD 2110 Spring 2019 Lecture 6: Consequence of type, casting; function equals
CMPE212 – Reminders Assignment 2 due next Friday.
Review for Midterm 3.
Inheritance Lakshmish Ramaswamy.
Presentation transcript:

Effective Java: Methods Common to All Objects SWE 619: Fall 2008 Paul Ammann

Methods Common to All Objects 2 Agenda Material From Joshua Bloch Effective Java: Programming Language Guide Cover Items 8 through 12 Methods Common to All Objects Was Items 7 through 11 in 1 st Edition Moral: Contract model = Industry Practice!

Methods Common to All Objects 3 Item 8 Obey the general contract when overriding equals. Overriding seems simple, but there are many ways to get it wrong. Best approach – Avoid! Works if: Each instance of a class is unique You don’t care if class has logical equality The superclass equals is satisfactory Class is not public and equals never used

Methods Common to All Objects 4 General contract for equals Reflexive x.equals(x) must be true Symmetric x.equals(y) iff y.equals(x) Transitive x.equals(y), y.equals(z) implies x.equals(z) Consistency… Null values: x.equals(null) is always false

Methods Common to All Objects 5 How hard could this be? Reflexivity is pretty much automatic Symmetry is not: Example CaseInsensitiveString private String s; // broken – violates symmetry public boolean equals (Object o) { if (o instanceof CaseInsensitiveString) return s.equalsIgnoreCase( ((CaseInsensitiveString) o).s); if (o instance of String) // Not Symmetric! return s.equalsIgnoreCase((String) o); return false; }

Methods Common to All Objects 6 Why does this violate symmetry? Consider this code: Object x = new CaseInsenstiveString (“abc”); Object y = “Abc”; // y is a String if (x.equals(y)) {…} // evaluates true, so execute if (y.equals(x)) {…} // evaluates false, so don’t… Dispatching of equals() calls First equals() call to CaseInsensitiveString Second equals() call to String This is horrible!

Methods Common to All Objects 7 Correct Implementation Avoid temptation to be “compatible” with the String class: CaseInsensitiveString is not a subclass of String! private String s; public boolean equals (Object o) { return (o instanceof CaseInsensitiveString) && (CaseInsensitiveString o).s. equalsIgnoreCase(s); }

Methods Common to All Objects 8 Symmetry and Transitivity Surprisingly difficult – general result about inheritance Example: A 2D Point class State is two integer values x and y equals() simply compares x and y values An extension to include color public class ColorPoint extends Point What should equals() do?

Methods Common to All Objects 9 Preliminaries: What does equals in Point look like? public class Point { // routine code private int x; private int y;... public boolean equals(Object o) { if (!(o instance of Point)) return false; Point p = (Point) o; return p.x == x && p.y == y; }

Methods Common to All Objects 10 Choice 1 for equals() in ColorPoint Have equals() return true iff the other point is also a ColorPoint: // broken – violates symmetry public boolean equals(Object o) { if (!(o instance of ColorPoint)) return false; ColorPoint cp = (ColorPoint o); return super.equals(o) && cp.color == color; }

Methods Common to All Objects 11 Problem Symmetry is broken Different results if comparing: ColorPoint cp = new ColorPoint (1, 2, RED); Point p = new Point (1,2); p.equals(cp), cp.equals(p) differ Unfortunately, equals() in Point doesn’t know about ColorPoints (nor should it…) So, try a different approach…

Methods Common to All Objects 12 Choice 2 for equals() in ColorPoint Have equals() ignore color when doing “mixed” comparisons: // broken – violates transitivity public boolean equals(Object o) { if (!(o instance of Point)) return false; // If o is a normal Point, be colorblind if (!o instanceof ColorPoint) return o.equals(this); ColorPoint cp = (ColorPoint o); return super.equals(o) && cp.color == color; }

Methods Common to All Objects 13 Now symmetric, but not transitive! Consider the following example ColorPoint p1 = new ColorPoint(1,2,RED); Point p2 = new Point(1,2); ColorPoint p3 = new ColorPoint(1,2,BLUE); The following are true: p1.equals(p2) p2.equals(p3) But not p1.equals(p3)!

Methods Common to All Objects 14 The real lesson There is no way to extend an instantiable class and add an aspect while preserving the equals contract. Note that abstract superclass definitions of equals() are fine. (See Bloch Item 20) Wow! Inheritance is hard! Solution: Favor composition over inheritance (Item 16). Note: This was not well understood when some Java libraries were built…

Methods Common to All Objects 15 How to implement equals() Use == to see if argument is a reference to this (optimization) Use instanceof to check if argument is of the correct type (properly handles null) Cast the argument to the correct type Check each “significant” field (see AF() from Liskov…) Check reflexivity, symmetry, transitivity

Methods Common to All Objects 16 What not to do Don’t be too clever Don’t use unreliable resources, such as IP addresses Don’t substitute another type for Object public boolean equals (MyClass o) // Wrong! Overloads equals – does not override it! Don’t throw NullPointerException or ClassCastException

Methods Common to All Objects 17 Item 9 Always override hashCode() when you override equals() Contract: hashCode must return same integer on different calls, as long as equals() unchanged If x.equals(y), then x, y have same hashcode It is not required that unequal objects have different hashcodes.

Methods Common to All Objects 18 Second provision is key Suppose x.equals(y), but x and y have different values for hashCode() Consider this code: Map m = new HashMap(); m.put(x, “Hello”); // expect x to map to Hello m.get(y) should return Hello, since x.equals(y), but it doesn’t! Ouch!

Methods Common to All Objects 19 How to implement hashCode Avoid really bad implementations public int hashCode() { return 42;} Hash table now performs terribly (but, at least, correctly…) Start with some nonzero value (eg 17) (Repeatedly) compute int hashCode “c” for each “significant field” (see AF, Liskov) Various rules for each data type Combine: result = result*37 + c;

Methods Common to All Objects 20 Optimize hashCode() for immutable objects No reason to recompute hashcode Maybe no reason to compute at all! // Lazy initialization example private int hashCode = 0; public int hashCode() { if (hashCode == 0) { …} // needed now, so compute hashCode else return hashCode; }

Methods Common to All Objects 21 Item 10 Always override toString() Bloch’s advice is straight out of Liskov Return all “significant” information (see AF) If you specify a format, be precise Others may parse your toString representations API should include access to all information contained in toString() representation Otherwise, others are forced to parse representation See Liskov notion of adequacy

Methods Common to All Objects 22 Item 11 Override clone() judiciously Cloneable is a “mixin” interface Unfortunately, it fails to provide any methods clone() is defined in Object (protected) Contract: Create a copy such that x.clone() != x x.clone().getClass() == x.getClass() Should have x.clone().equals(x) No constructors are called Contrast with C++ copy constructor

Methods Common to All Objects 23 What a strange contract The requirement on classing is too weak A programmer calling super.clone() wants an instance of the subclass, not the superclass. The only way to do this is to call super.clone() all the way up to Object. Explicit use of constructors gives the wrong class. Rule: Always implement clone() by calling super.clone().

Methods Common to All Objects 24 The role of mutability If a class has only primitive fields or immutable references as fields, super.clone() returns exactly what you want For objects with mutable references, “deep copies” are required. Example: cloning a Stack class that uses a Vector for a representation. Representation Vector must also be cloned. So, call super.clone(), then clone Vector

Methods Common to All Objects 25 Other Cloning problems Cloning may be a problem with final fields Cloning recursively may not be sufficient Result: You may be better off not implementing Cloneable Providing a separate copy mechanism may be preferable. Copy Constructor: public Yum (Yum yum) Factory: public static Yum newInstance(Yum yum)

Methods Common to All Objects 26 Item 12 Consider Implementing Comparable Contract Returns negative, zero, or positive depending on order of this and specified object sgn(x.compareTo(y) == -sgn(y.compareTo(x)) compareTo() must be transitive If x.compareTo(y) == 0, x and y must consistently compare to all values z. Recommended that x.compareTo(y) == 0 iff x.equals(y) Note that compareTo() can throw exceptions

Methods Common to All Objects 27 Elements of the contract The same issue with equals() arises in the case of inheritance: There is simply no way to extend an instantiable class with a new aspect while preserving the compareTo contract. Same workaround – Favor composition over inheritance Some Java classes violate the consistency requirement with equals(). Example: The BigDecimal class

Methods Common to All Objects 28 BigDecimal Example //This is horrible! Object x = new BigDecimal(“1.0”); Object y = new BigDecimal(“1.00”); // !x.equals(y), but x.compareTo(y) == 0 Set s = new HashSet(); Set t = new TreeSet(); s.add(x); s.add(y); // HashSet uses equals, so s has 2 elements t.add(x); t.add(y); // TreeSet uses compareTo, so t has 1 element