The Artima Developer Community

Object Design Workshop by Bill Venners
Designing with Types
Lecture Handout

Agenda


instanceof and Downcasting


The OO Way


Why Dynamic Binding?


Discussion


Can you dance()?

1 // In file ex5/Hippopotamus.java
2
3 class Hippopotamus {
4
5     void sing() {
6         System.out.println("Hippo singing!");
7     }
8 }
9

1 // In file ex5/DancingHippopotamus.java
2
3 class DancingHippopotamus
4     extends Hippopotamus {
5
6     void dance() {
7         System.out.println("Hippo dancing!");
8     }
9 }

 1 // In file ex5/Example5.java
 2 import java.util.ArrayList;
 3 import java.util.Collection;
 4 import java.util.Iterator;
 5
 6 class Example5 {
 7
 8     public static void main(String[] args) {
 9
10         makeHippoPerform(new Hippopotamus());
11         makeHippoPerform(new DancingHippopotamus());
12     }
13
14     // Client must pass a Hippopotamus
15     static void makeHippoPerform(
16         Hippopotamus hippo) {
17
18         hippo.sing();
19         if (hippo instanceof DancingHippopotamus) {
20             DancingHippopotamus dh =
21                 (DancingHippopotamus) hippo;
22             dh.dance();
23         }
24     }
25 }

dance()-eth Thou?

1 // In file ex5/Hippopotamus.java
2
3 class Hippopotamus {
4
5     void sing() {
6         System.out.println("Hippo singing!");
7     }
8 }
9

1 // In file ex5/DancingHippopotamus.java
2
3 class DancingHippopotamus
4     extends Hippopotamus {
5
6     void dance() {
7         System.out.println("Hippo dancing!");
8     }
9 }

 1 // In file ex5/Example5b.java
 2 import java.lang.reflect.Method;
 3 import java.lang.reflect.InvocationTargetException;
 4
 5 class Example5b {
 6
 7     public static void main(String[] args) {
 8
 9         makeHippoPerform(new Hippopotamus());
10         makeHippoPerform(new DancingHippopotamus());
11     }
12
13     // Client must pass a Hippopotamus
14     static void makeHippoPerform(
15         Hippopotamus hippo) {
16
17         hippo.sing();
18         Class c = hippo.getClass();
19         try {
20             Method method = c.getDeclaredMethod(
21                 "dance", new Class[0]);
22
23             try {
24                 method.invoke(hippo, new Object[0]);
25             }
26             catch (InvocationTargetException e) {
27                 System.out.println("Can't dance!");
28             }
29             catch (IllegalAccessException e) {
30                 System.out.println("Not allowed to dance!");
31             }
32         }
33         catch (NoSuchMethodException e) {
34         }
35     }
36 }

Why instanceof and Downcasting?

13     // Client must pass a Hippopotamus
14     static void makeHippoPerform(
15         Hippopotamus hippo) {
16
17         hippo.sing();
18         Class c = hippo.getClass();
19         try {
20             Method method = c.getDeclaredMethod(
21                 "dance", new Class[0]);
22
23             try {
24                 method.invoke(hippo, new Object[0]);
25             }
26             catch (InvocationTargetException e) {
27                 System.out.println("Can't dance!");
28             }
29             catch (IllegalAccessException e) {
30                 System.out.println("Not allowed to dance!");
31             }
32         }
33         catch (NoSuchMethodException e) {
34         }
35     }
14     // Client must pass a Hippopotamus
15     static void makeHippoPerform(
16         Hippopotamus hippo) {
17
18         hippo.sing();
19         if (hippo instanceof DancingHippopotamus) {
20             DancingHippopotamus dh =
21                 (DancingHippopotamus) hippo;
22             dh.dance();
23         }
24     }

Discussion


Runtime Class Information


Class and Type


The Class File

Java compiler creates class files, a binary format that contains information about the class, such as:

Class Info in the JVM


Using Class Information


Class Class


Printing Class Information

1 // In file ex5/Hippopotamus.java
2
3 class Hippopotamus {
4
5     void sing() {
6         System.out.println("Hippo singing!");
7     }
8 }
9


1 // In file ex5/DancingHippopotamus.java
2
3 class DancingHippopotamus
4     extends Hippopotamus {
5
6     void dance() {
7         System.out.println("Hippo dancing!");
8     }
9 }


  1 // In file ex5/Example5c.java
  2 import java.util.ArrayList;
  3 import java.util.Collection;
  4 import java.util.Iterator;
  5 import java.lang.reflect.*;
  6
  7 public class Example5c {
  8
  9     public static void main(String[] args) {
 10
 11         ArrayList hippos = new ArrayList();
 12         hippos.add(new Hippopotamus());
 13         hippos.add(new DancingHippopotamus());
 14         hippos.add(hippos);
 15         hippos.add(new String("Hi There!"));
 16
 17         Iterator it = hippos.iterator();
 18         while (it.hasNext()) {
 19             printClassInfo(it.next());
 20         }
 21     }
 22
 23     static void printModifiers(int modifiers) {
 24
 25         if (Modifier.isPrivate(modifiers)) {
 26             System.out.print("private ");
 27         }
 28         else if (Modifier.isProtected(modifiers)) {
 29             System.out.print("protected ");
 30         }
 31         else if (Modifier.isPublic(modifiers)) {
 32             System.out.print("public ");
 33         }
 34
 35         if (Modifier.isAbstract(modifiers)) {
 36             System.out.print("abstract ");
 37         }
 38         if (Modifier.isStatic(modifiers)) {
 39             System.out.print("static ");
 40         }
 41         if (Modifier.isFinal(modifiers)) {
 42             System.out.print("final ");
 43         }
 44         if (Modifier.isTransient(modifiers)) {
 45             System.out.print("transient ");
 46         }
 47         if (Modifier.isVolatile(modifiers)) {
 48             System.out.print("volatile ");
 49         }
 50         if (Modifier.isSynchronized(modifiers)) {
 51             System.out.print("synchronized ");
 52         }
 53         if (Modifier.isNative(modifiers)) {
 54             System.out.print("native ");
 55         }
 56     }
 57
 58     static void printClassInfo(Object o) {
 59
 60         System.out.println("------------------------");
 61
 62         Class c = o.getClass();
 63
 64         System.out.println("Name: " + c.getName());
 65
 66         Class superclass = c.getSuperclass();
 67         if (superclass != null) {
 68             System.out.println("Superclass: "
 69                 + superclass.getName());
 70         }
 71
 72         System.out.println("Interfaces:");
 73         Class[] interfaces = c.getInterfaces();
 74         for (int i = 0; i < interfaces.length; ++i) {
 75             System.out.println("\t" + interfaces[i].getName());
 76         }
 77
 78         System.out.println("Fields:");
 79         Field[] fields = c.getDeclaredFields();
 80         for (int i = 0; i < fields.length; ++i) {
 81             System.out.print("\t");
 82             printModifiers(fields[i].getModifiers());
 83             System.out.println((fields[i].getType()).getName()
 84                 + " " + fields[i].getName() + ";");
 85         }
 86
 87         System.out.println("Methods:");
 88         Method[] methods = c.getDeclaredMethods();
 89         for (int i = 0; i < methods.length; ++i) {
 90
 91             System.out.print("\t");
 92             printModifiers(methods[i].getModifiers());
 93
 94             System.out.print((methods[i].getReturnType()).getName()
 95                 + " " + methods[i].getName() + "(");
 96
 97             Class[] params = methods[i].getParameterTypes();
 98             for (int j = 0; j < params.length; ++j) {
 99                 System.out.print(params[j].getName());
100                 if (j != 0 && j != params.length - 1) {
101                     System.out.print(", ");
102                 }
103             }
104
105             System.out.println(");");
106         }
107     }
108 }
109


  1 ------------------------
  2 Name: Hippopotamus
  3 Superclass: java.lang.Object
  4 Interfaces:
  5 Fields:
  6 Methods:
  7 	void sing();
  8 ------------------------
  9 Name: DancingHippopotamus
 10 Superclass: Hippopotamus
 11 Interfaces:
 12 Fields:
 13 Methods:
 14 	void dance();
 15 ------------------------
 16 Name: java.util.ArrayList
 17 Superclass: java.util.AbstractList
 18 Interfaces:
 19 	java.util.List
 20 	java.lang.Cloneable
 21 	java.io.Serializable
 22 Fields:
 23 	private transient [Ljava.lang.Object; elementData;
 24 	private int size;
 25 Methods:
 26 	private void RangeCheck(int);
 27 	public void add(intjava.lang.Object);
 28 	public boolean add(java.lang.Object);
 29 	public boolean addAll(intjava.util.Collection);
 30 	public boolean addAll(java.util.Collection);
 31 	public void clear();
 32 	public java.lang.Object clone();
 33 	public boolean contains(java.lang.Object);
 34 	public void ensureCapacity(int);
 35 	public java.lang.Object get(int);
 36 	public int indexOf(java.lang.Object);
 37 	public boolean isEmpty();
 38 	public int lastIndexOf(java.lang.Object);
 39 	private synchronized void readObject(java.io.ObjectInputStream);
 40 	public java.lang.Object remove(int);
 41 	protected void removeRange(intint);
 42 	public java.lang.Object set(intjava.lang.Object);
 43 	public int size();
 44 	public [Ljava.lang.Object; toArray();
 45 	public [Ljava.lang.Object; toArray([Ljava.lang.Object;);
 46 	public void trimToSize();
 47 	private synchronized void writeObject(java.io.ObjectOutputStream);
 48 ------------------------
 49 Name: java.lang.String
 50 Superclass: java.lang.Object
 51 Interfaces:
 52 	java.io.Serializable
 53 	java.lang.Comparable
 54 Fields:
 55 	private [C value;
 56 	private int offset;
 57 	private int count;
 58 	private static java.lang.ThreadLocal btcConverter;
 59 	private static java.lang.ThreadLocal ctbConverter;
 60 	private static final long serialVersionUID;
 61 	private static final [Ljava.io.ObjectStreamField; serialPersistentFields;
 62 	public static final java.util.Comparator CASE_INSENSITIVE_ORDER;
 63 Methods:
 64 	public char charAt(int);
 65 	public int compareTo(java.lang.Object);
 66 	public int compareTo(java.lang.String);
 67 	public int compareToIgnoreCase(java.lang.String);
 68 	public java.lang.String concat(java.lang.String);
 69 	public static java.lang.String copyValueOf([C);
 70 	public static java.lang.String copyValueOf([Cint, int);
 71 	public boolean endsWith(java.lang.String);
 72 	public boolean equals(java.lang.Object);
 73 	public boolean equalsIgnoreCase(java.lang.String);
 74 	private static sun.io.ByteToCharConverter getBTCConverter(java.lang.String);
 75 	public [B getBytes();
 76 	public void getBytes(intint, [B, int);
 77 	public [B getBytes(java.lang.String);
 78 	private [B getBytes(sun.io.CharToByteConverter);
 79 	private static sun.io.CharToByteConverter getCTBConverter(java.lang.String);
 80 	public void getChars(intint, [C, int);
 81 	public int hashCode();
 82 	public int indexOf(int);
 83 	public int indexOf(intint);
 84 	public int indexOf(java.lang.String);
 85 	public int indexOf(java.lang.Stringint);
 86 	public native java.lang.String intern();
 87 	public int lastIndexOf(int);
 88 	public int lastIndexOf(intint);
 89 	public int lastIndexOf(java.lang.String);
 90 	public int lastIndexOf(java.lang.Stringint);
 91 	public int length();
 92 	public boolean regionMatches(intjava.lang.String, int, int);
 93 	public boolean regionMatches(booleanint, java.lang.String, int, int);
 94 	public java.lang.String replace(charchar);
 95 	public boolean startsWith(java.lang.String);
 96 	public boolean startsWith(java.lang.Stringint);
 97 	public java.lang.String substring(int);
 98 	public java.lang.String substring(intint);
 99 	public [C toCharArray();
100 	public java.lang.String toLowerCase();
101 	public java.lang.String toLowerCase(java.util.Locale);
102 	public java.lang.String toString();
103 	public java.lang.String toUpperCase();
104 	public java.lang.String toUpperCase(java.util.Locale);
105 	public java.lang.String trim();
106 	public static java.lang.String valueOf(char);
107 	public static java.lang.String valueOf(double);
108 	public static java.lang.String valueOf(float);
109 	public static java.lang.String valueOf(int);
110 	public static java.lang.String valueOf(long);
111 	public static java.lang.String valueOf(java.lang.Object);
112 	public static java.lang.String valueOf(boolean);
113 	public static java.lang.String valueOf([C);
114 	public static java.lang.String valueOf([Cint, int);

Why Design with Types?


Runtime Class Info is Not Evil


Discussion


Sponsored Links

Copyright © 1996-2007 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us