Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
1
Java Object Model
Or, way down the rabbit hole…
2
Type
• Definition: – a set of values and – a set of operations that can be applied to those values
• Java is a strongly-typed language: compiler & run-time system ensure that programs don’t violate type system rules – Compiler catches most illegal operation attempts – Java virtual machine catches a few (e.g. invalid casts)
• By contrast, C/C++ not strongly typed
3
Types in Java
• Primitive: int, double, char, boolean, etc. • Class • Interface • Array
– Array in itself is distinct type – Individual array elements are of some
component type • Null
4
Values in Java
• Every value is one of the following: – Value of a primitive type (e.g. 1.4, -9, ‘c’) – Reference to a class object – Reference to an array – null
• Notes: – No such thing as a value of an interface type – Void is not a data type – just a method tag to indicate no
return value
5
Subtype relationship
• Subtype contains subset of values of a given type
• Can use subtype where supertype is specified
6
S is a subtype of T if: 1. S and T are the same type 2. S and T are both class types, and T is a direct or indirect superclass
of S 3. S is a class type, T is an interface type, and S or one of its
superclasses implements T 4. S and T are both interface types, and T is a direct or indirect
superinterface of S 5. S and T are both array types, and the component type of S is a
subtype of the component type of T 6. S is not a primitive type and T is the type Object 7. S is an array type and T is Cloneable or Serializable 8. S is the null type and T is not a primitive type
7
Examples
ListIterator is a subtype of Iterator
Container is a subtype of Component
JButton is a subtype of Component
FlowLayout is a subtype of Layout Manager
8
Examples
• Rectangle[] is a subtype of Shape[] • int[] is a subtype of Object • int is not a subtype of long • long is not a subtype of int • int[] is not a subtype of Object[]
9
Array Types
• Recall rule 5: S[] is a subtype of T[] if S is a subtype of T
• Example: Rectangle [] r = new Rectangle[10]; Can store object r in an array of Shape, since
Rectangle is a subset of Shape: Shape [] s = r; Variables r and s both refer to the same array
10
Example continued
What happens if a non-Rectangle Shape is stored in s[]? • Throws ArrayStoreException at runtime • Every array object remembers its component type • Could store a subtype of Rectangle (but not just of
Shape) without throwing exception
11
Primitive type wrappers
• Many services in Java API deal with Objects; for example, ArrayLists are collections of Objects
• Primitive types are not subtypes of Object • Useful to have classes to “wrap” primitive
types so they can avail themselves of Object services
12
Wrapper classes in Java
• Wrapper classes exist for all primitive types: – Integer, Short, Long – Byte, Character – Float, Double – Boolean
• Wrapper classes are immutable
13
Wrapper class methods
• Constructor take primitive type argument: double num = 3.14159; Double d = new Double(num);
• Can “unwrap” to get primitive value: num = d.doubleValue();
• Some wrappers have parse methods that convert from String to primitive: String s = “52406”; int n = Integer.parseInt(s);
14
Type inquiry
• Can use instanceof operator to test whether an expression is a reference to an object of a given type or one of its subtypes
• Operator returns true if expression is a subtype of the given type; otherwise (including in the case of a null expression) returns false
15
Example using instanceof JPanel picPanel = new JPanel(); ArrayList images = new ArrayList(); … for (int x=0; x<images.size(); x++) { Object o = images.get(x); if (o instanceof Icon) { Icon pic = (Icon)o; picPanel.add(pic); } }
16
Notes on instanceof
• Can test whether value is subtype of given type, but doesn’t distinguish between subtypes
• In previous example, o could be any kind of Icon (since Icon is an interface, couldn’t be an Icon per se)
17
Getting exact class of object
• Can get exact class of object reference by invoking getClass() method
• Method getClass() returns an object of type Class; can invoke getName() on Class object to retrieve String containing class name: System.out.println(o.getClass().getName());
18
Class object
• Type descriptor • Contains information about a given type,
e.g. type name and superclass
19
Ways to obtain Class object
• Call getClass() on an object reference • Call static Class method forName():
Class c = Class.forName(“java.awt.Rectangle”); • Add suffix .class to a type name to obtain a
literal Class object: Class c = Rectangle.class;
20
Notes on Class type
• There is exactly one Class object for every type loaded in the virtual machine
• Class objects describe any type, including primitive types
• Can use == to test whether two Class objects describe same type: if (o.getClass() == Rectangle.class) True if o is exactly a Rectangle (not a subclass)
21
Arrays and getClass()
• When applied to an array, getClass() returns a Class object that describes the array type
• Use Class method getComponentType() to get a Class object describing the array’s components
• Use Class method isArray() to determine whether or not an object is an array
22
Arrays and Class.getName()
Array name is built from these rules: [type Where type is one of the following: B: byte C: char D: double F: float I: int J: long S: short Z: boolean For non-primitive types, replace “type” with Lname; (where name is the name of the class or interface – note semicolon)
23
Reflection
• Mechanism by which a program can analyze its objects & their capabilities at runtime
• Java API includes several reflection classes, described on next slide
24
Reflection Classes
• Class: describes a type • Package: describes a package • Field: describes field; allows inspection,
modification of all fields • Method: describes method, allows its invocation
on objects • Constructor: describes constructor, allows its
invocation • Array: has static methods to analyze arrays
25
Class class object
• Includes class name and superclass of an object, as we have already seen; also includes: – interface types class implements – package of class – names & types of all fields – names, parameter types, return types of all
methods – parameter types of all constructors
26
Class class methods
• getSuperClass() returns Class object that describes superclass of a given type; returns null if type is Object or is not a class
• getInterfaces() returns array of Class objects describing interface types implemented or extended; if type doesn’t implement or extend any interfaces, returns array of length 0 (only returns direct superinterfaces)
27
Class class methods
• getPackage() returns Package object; Package has getName() method which returns String containing package name
• getDeclaredFields() returns array of Field objects declared by this class or interface – includes public, private, protected & package-
visible fields – includes both static & instance fields – does not include superclass fields
28
Field class methods
• getName(): returns String containing field name • getType(): returns Class describing field type • getModifiers(): returns an int whose various bits
are set to indicate whether field is public, private, protected, static, or final: use static Modifier methods isPublic, isPrivate, isProtected, isStatic, isFinal to test this value
29
Example - prints all static fields of java.lang.Math
Field[] fields = Math.class.getDeclaredFields(); for (int x = 0; x < fields.length; x++) if(Modifier.isStatic(fields[x].getModifiers())) System.out.println(fields[x].getName());
30
More Class class methods
• getDeclaredConstructors() returns array of Constructor objects describing class constructors
• Constructor object has method getParameterTypes that returns an array of Class objects describing the constructor’s parameters
31
Example: printing Rectangle constructor information
Constructor cons[] = Rectangle.class.getDeclaredConstructors(); for (int=0; x < cons.length; x++) { Class [] params = cons[x].getParameterTypes(); System.out.println(“Rectangle(”); for (int y=0; y < params.length; y++) { if(y > 0) System.out.print(“, ”); System.out.print(params[y].getName()); } System.out.println(“)”); }
32
Output from example Rectangle() Rectangle(java.awt.Rectangle) Rectangle(int, int, int, int) Rectangle(int, int) Rectangle(java.awt.Point, java.awt.Dimension) Rectangle(java.awt.Point) Rectangle(java.awt.Dimension)
33
Class class’s getDeclaredMethods() method
• Returns array of Method objects • Method object methods include:
– getParameterTypes(): returns array of parameter types
– getName(): returns method name – getReturnType(): returns Class object
describing return value type
34
Obtaining single Method or Constructor objects
• Class’s getDeclaredMethod() (note the singular) returns a Method object if supplied with a method name and array of parameter objects: Method m = Rectangle.class.getDeclaredMethod(“contains”, new
Class[]{int.class, int.class});
• For Constructor object: Constructor c = Rectangle.class.getDeclaredConstructor(new
Class[] {});
35
Method methods
• invoke(): can be used to call a method described by a Method object - need to: – supply implicit parameter (null for static methods) –
first argument, representing calling object – supply array of explicit parameter values (need to wrap
primitive types) – if method returns a value, invoke returns an Object;
need to cast or unwrap return value, as appropriate
36
Example - saying hello the hard way import java.lang.reflect.*; import java.io.*; public class SayHello { public static void main(String[]args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Method m = PrintStream.class.getDeclaredMethod (“println”, new Class[] {String.class}); m.invoke(System.out, new Object[] {“Hello!”}); } }
37
Example with return value
Method m = Math.class.getDeclaredMethod(“sqrt”, new Class[] {double.class}); Object r = m.invoke(null, new Object[] {new Double(10.24)}); double x = ((Double) r).doubleValue();
38
Inspecting objects
• Can use reflection mechanism to dynamically look up object fields as program runs
• To allow access to a field, call its setAccessible() method; example: Class c = object.getClass(); Field f = c.getDeclaredField(name); f.setAccessible(true);
39
Inspecting objects
• Once granted access, you can read and write any field of the object: Object value = f.get(object); f.set(object, value);
• Notes: – f must be a Field that describes a field of object;
otherwise, get and set throw exception – if field type is primitive, get returns & set expects a
wrapper – if field is static, supply null for object
40
Inspecting array elements
• Field allows read/write access to arbitrary field of object; Array works similarly on array objects – for array a with index x: – get() method: Object value = Array.get(a,x) – set() method: Array.set(a,x,value);
41
Inspecting array elements
• Finding length of array a: int n = Array.getLength(a);
• Creating new array (twice as large) with static method newInstance():
Object newArray = Array.newInstance( a.getClass().getComponentType(), 2 * Array.getLength(a) + 1); System.arraycopy(a, 0, newArray, 0, Array.getLength(a)); a = newArray;
42
Object class
• Superclass for all Java classes • Any class without explicit extends clause is
a direct subclass of Object • Methods of Object include:
– String toString() – boolean equals (Object other) – int hashCode() – Object clone()
43
Method toString()
• Returns String representation of object; describes state of object
• Automatically called when: – Object is concatenated with a String – Object is printed using print() or println() – Object reference is passed to assert statement of
the form: assert condition : object
44
Example
Rectangle r = new Rectangle (0,0,20,40); System.out.println(r);
Prints out: java.awt.Rectangle[x=0,y=0,width=20,height=40]
45
More on toString()
• Default toString() method just prints (full) class name & hash code of object
• Not all API classes override toString() • Good idea to implement for debugging purposes:
– Should return String containing values of important fields along with their names
– Should also return result of getClass().getName() rather than hard-coded class name
46
Overriding toString(): example public class Employee { public String toString() { return getClass().getName() + "[name=" + name + ",salary=" + salary + "]"; } ... }
Typical String produced: Employee[name=John Doe,salary=40000]
47
Overriding toString in a subclass
• Format superclass first • Add unique subclass details • Example:
public class Manager extends Employee {
public String toString() { return super.toString() + "[department=" + department + "]"; } ...
}
48
Example continued
• Typical String produced: Manager[name=Mary Lamb,salary=75000][department=Admin]
• Note that superclass reports actual class name
49
Equality testing
• Method equals() tests whether two objects have same contents
• By contrast, == operator test 2 references to see if they point to the same object (or test primitive values for equality)
• Need to define for each class what “equality” means: – Compare all fields – Compare 1 or 2 key fields
50
Equality testing
• Object.equals tests for identity: public class Object { public boolean equals(Object obj) { return this == obj; } ... }
• Override equals if you don't want to inherit that behavior
51
Overriding equals()
• Good practice to override, since many API methods assume objects have well-defined notion of equality
• When overriding equals() in a subclass, can call superclass version by using super.equals()
52
Requirements for equals() method
• Must be reflexive: for any reference x, x.equals(x) is true
• Must be symmetric: for any references x and y, x.equals(y) is true if and only if y.equals(x) is true
• Must be transitive: if x.equals(y) and y.equals(z), then x.equals(z)
• If x is not null, then x.equals(null) must be false
53
The perfect equals() method
public boolean equals(Object otherObject) { if (this == otherObject) return true; if (otherObject == null) return false; if (getClass() != otherObject.getClass()) return false; ... }
54
Hashing
• Technique used to find elements in a data structure quickly, without doing full linear search
• Important concepts: – Hash code: integer value used to find array index for
data storage/retrieval – Hash table: array of elements arranged according to
hash code – Hash function: computes index for element; uses
algorithm likely to produce different indexes for different objects to minimize collisions
55
Hashing in Java
• Java library contains HashSet and HashMap classes – Use hash tables for data storage – Since Object has a hashCode method (hash
function), any type of object can be stored in a hash table
56
Default hashCode()
• Hashes memory address of object; consistent with default equals() method
• If you override equals(), you should also redefine hashCode()
• For class you are defining, use product of hash of each field and a prime number, then add these together – result is hash code
57
Example
public class Employee { public int hashCode() { return 11 * name.hashCode() + 13 * new Double(salary).hashCode(); } ... }
58
Object copying
• Shallow copy – Copy of an object reference is another reference
to the same object – Happens with assignment operator
• Deep copy – Actual new object created, identical to original – A.K.A cloning
59
Method clone() must fulfill 3 conditions
• X.clone() != X • X.clone().equals(X) • X.clone().getClass() == X.getClass()
60
Object.clone()
• Default method is protected • If a class wants clients to be able to clone its
instances, must: – Redefine clone() as public method – Implement Cloneable interface
61
Cloneable
• Interface that specifies no methods: public interface Cloneable {}
• Strictly “tagging” interface; can be used to test if object can be cloned: if (x instanceof Cloneable) …
• If class doesn’t implement this interface, Object.clone() throws a CloneNotSupportedException (checked)
62
Example clone() method (v 1.0) public class Employee implements Cloneable { public Object clone() { try { return super.clone(); } catch(CloneNotSupportedException e) { return null; // won't happen } } ... }
63
Shallow cloning
• Object.clone() uses assignment – makes shallow copy of all fields
• If fields are object references, original and clone share common subobjects
• Not a problem for immutable fields (e.g. Strings) but programmer-written clone() methods must clone mutable fields
• Rule of thumb: if you extend a class that defines clone(), redefine clone()
64
Example clone() method (v 2.0) public class Employee implements Cloneable { public Object clone() { try { Employee cloned = (Employee) super.clone(); cloned.hireDate = (Date) hireDate.clone(); return cloned; } catch(CloneNotSupportedException e) { return null; } } ... }
Components
• Component: a software construct that encapsulates more functionality than a single class • Can use a set of components to construct an
application without much additional programming
• Visual Basic/ActiveX controls exemplify the component model of programming
Components & Java Beans
• JavaBeans: Java’s (partial) implementation of the component model
• Capabilities of a bean: • Can execute methods • Can reveal properties • Can emit events
Bean Properties
• Not necessarily instance variables – may be stored externally
• Have getter and setter methods (which may do more work than just/getting setting an instance variable, even if the property is an instance variable)
Bean Properties
• Java doesn’t really support components directly: beans rely on naming conventions for standardization
• Setter method names start with set, getter with get (exception Boolean getters – use is)
Beans & Façade pattern
• Java Beans work according to the Façade pattern: • Each bean may consist of multiple classes, but
a single class is chosen as the façade • Clients call on façade method, which can call
methods from other classes • Façade class reveals subsystem class
capabilities; subsystem classes don’t need to be aware of the facade
Beans & Reflection
• Beans are intended to be edited in a builder environment (such an environment is built into NetBeans)
• When bean is loaded into builder environment, façade class is searched for methods that match the conventional naming scheme – this is an example of the reflection mechanism at work