Download Java Review - Lecture Slides | Programming Language | CMSC 433 and more Study notes Programming Languages in PDF only on Docsity!
CMSC 433: Programming Language Technology and Paradigms Fall 2003
Java Review
Michael Hicks
September 4, 2003
Administrivia
- Project 1 will be posted today, due Sep 17
- You should have received e-mail from the TA
- Reading: (today) Liskov ch. 1, 2 (Tues) ch. 4
- Supplemental: Eckel ch. 1, 7, 8 (first half), 9
Selected Java Tidbits
- Code reuse with subtyping and inheritance
- Every object is an Object
- Methods can be overloaded and overridden
- Object variables are references
- Exceptions
Java Classes and Code Reuse
- Each object is an instance of a class
- Even an array is an object
- Classes can be reused in two ways
- Subtyping
- Extension (inheritance)
Beware! Inheritance? Subtyping
- U extends T implies U ≤ T
- U ≤ T does not imply U extends T
- Why?
- Subtyping of primitives, e.g. char ≤ int
- Subtyping of interfaces
- Try to keep these ideas separate in your head
Java Interfaces
- Inheritance
- Hierarchical code sharing (“is-a”)
- Interfaces
Object
Number
Comparable Inherits from public int compareTo(Object o)
Implements
Interfaces
- An interface lists supported (public) methods
- No constructors or implementations allowed
- Can have final static variables
- A class can implement (be a subtype of) zero or more interfaces
- Given some interface I , declaring I x = ... means
- x must refer to an instance of a class that implements I, or else null
Interface example
public interface Comparable { int compareTo(Object o) } public class Util { public static void sort(Comparable []) { … } } public class Choices implements Comparable { public int compareTo(Object o) { return … ; } } … Choices [] options = … ; Util.sort(options); …
Choices ≤ Comparable
Choices [] ≤ Comparable []
Invoking Methods
o.m(arg1, arg2, ..., argn);
- Question:
- Which method m will actually get run?
- Answer:
- It depends on the declared type and the actual type of o
Declared vs. Actual Types
- The actual type of an object is its allocated type
- Integer o = new Integer (1);
- A declared type is a type at which an object is being viewed - Object o = new Integer(1); - class Foo { void m( Object o) { return; } }
- Each object always has one actual type , but can have many declared types
Overriding
- Define a method also defined by a
superclass
class Parent { int cost; void add(int x) { cost += x; } }
class Child extends Parent { void add(int x) { if (x > 0) cost += x; } }
Overriding (cont’d)
- Method with same name and argument types in child class overrides method in parent class
- Arguments and result types must be identical
- otherwise you are overloading the method (e.g., equals from last time)
- Must raise the same or fewer exceptions
- Can override/hide instance variables
- both variables will exist, but don’t do it
Instance vs. static
- static – the data is stored “with the class”
- static variables allocated once, no matter how many objects created
- static methods are not specific to any class instance, so can’t refer to this or super
- Can reference class variables and methods
through either class name or an object ref
- Clearer to reference via the class name
Instance vs. static
int foo
int foo
int foo
Foo int bar;
Public class Foo { int foo; static int bar; }
Class definition
Class implementation
Objects of class Foo
Static Method Dispatch
- Let B be a subclass of A , and suppose we have A a = new B();
- Then
- class (static) methods invoked on a will get the methods for the declared type A - Invoking class methods via objects strongly discouraged; invoke through the class instread ( A.m() instead of a.m() )
Actual type B
Declared type A
Simple Method Dispatch Example
public class A { String f() { return “A.f() “; } static String g() { return “A.g() “; } } public class B extends A { String f() { return “B.f() “; } static String g() { return “B.g() “; } public static void main(String args[]) { A a = new B(); B b = new B(); System.out.println(a.f() + a.g() + b.f() + b.g()); } }
java B generates : B.f() A.g() B.f() B.g()
Java Inheritance Hierarchy
- Everything inherits from Object*
- Allows sharing, generics, and more
- Well, almost: there are primitive int, long, float, etc.
Object
Thread
Integer
Number
…
Object s have methods
- All objects, therefore, inherit them
- Default implementations may not be the ones you want
public boolean equals (Object that) public String toString () public int hashCode () public void finalize ()
“conceptual” equality returns print representation key for hash table called when object garbage-collected
Subtype Polymorphism
- A data structure Set that implements sets of
Object s
- can summarily hold String s
- or images
- or … anything!
- The trick is getting them back out:
- When given an Object , you have to downcast it
Downcasting
- (Foo) o
- If o has declared type U , actual type T ≤ U
- Compile-time error if Foo is not a subtype of U
- Cast succeeds when T ≤ Foo
- Run-time exception if Foo ≤ T and T Foo
- No run-time effect on success
- Just treats the result as if it were of type Foo
- o instanceof Foo
- Predicate: true if cast ( Foo )o would succeed
References and call-by-value
class MyInt { int x; public MyInt(int x) { this.x = x; } } class Foo { void inc(int x) { x = x+1; } void inc(MyInt o) { o.x = o.x+1; } } }
MyInt o = new MyInt(5); int x = 5; Foo f = new Foo(); f.inc(x); f.inc(o); System.out.println(x); System.out.println(o);
Prints: 5 6 Passing object expressions to methods copies the reference, not the object
Equality
- Object .equals(Object) method
- Structural (“conceptual”) equality
- == operator ( != as well)
- Operates on references, not objects
- True if arguments refer to same runtime object
- o == p implies o.equals(p)
Overriding Equals
class Foo { bool equals(Foo f) { … } // wrong! }
class Foo { bool equals(Object o) { … } // right! }
The first case creates an overloaded method, while the second overrides the parent ( Object ) method.
Preconditions
- Functions often have requirements on their inputs // Return maximum element in A[i..j] int findMax(int[] A, int i, int j) { ... } - A is non-empty - i and j must be non-negative - i and j must be less than A.length - i < j (maybe)
- These are called preconditions or requires clauses
Method throws declarations
- A method declares the exceptions it might throw
- public void openNext() throws UnknownHostException, EmptyStackException { … }
- Must declare any exception the method might throw - unless it is caught in (masked by) the method - includes exceptions thrown by called methods - certain built-in exceptions excluded
Exception Handling
- An exception of type T gets caught by first
catch with declared type U , where T ≤ U
- finally is always executed try { if (i == 0) return; myMethod(a[i]); } catch (ArrayIndexOutOfBounds e) { System.out.println(“a[] out of bounds”); } catch (MyOwnException e) { System.out.println(“Caught my error”); } catch (Exception e) { System.out.println(“Caught” + e.toString()); throw e; } finally { / stuff to do whether an exception / / was thrown or a return taken / }
Masking Exceptions
- Handle exception and continue while ((s = ...) != null) { try { FileInputStream f = new FileInputStream(s); ... } catch (FileNotFoundException e) { System.out.println(s + “ not found”); } }
Reflecting Exceptions
- Pass exception up to higher level
- Automatic support for throwing same exception
- Sometimes useful to throw different exception
try { ... a[0] ... } catch (IndexOutOfBoundsException e) { throw new EmptyException(“Arrays.min”); }