Advanced Java Course Reflection Reflection API What if

  • Slides: 23
Download presentation
Advanced Java Course Reflection

Advanced Java Course Reflection

Reflection API • What if you want to access information not just about the

Reflection API • What if you want to access information not just about the Object, but about that Object’s Class? • What if you want to access a method, field, or constructor whose name you don’t know at compile time?

Example: Web. Crawler timer • To optimize your Web. Crawler, first find out how

Example: Web. Crawler timer • To optimize your Web. Crawler, first find out how long each big operation is taking. – Getting content from URLs – Parsing pages – Setting up Database Connection & Statement – Deleting from the Database – Inserting into the Database – Other?

How to time an operation? • Without reflection: int start. Time = System. current.

How to time an operation? • Without reflection: int start. Time = System. current. Time. Millis(); do. Operation(. . . ); int end. Time = System. current. Time. Millis(); int duration = end. Time – start. Time; • Problem: Code is repeated every place you want to time an operation! Not clean at all. . .

A better way to time an operation • Object time. Method(String method. To. Call,

A better way to time an operation • Object time. Method(String method. To. Call, Class[] arg. Types, Object[] args, String time. To. Update. Field) {. . . } • time. Method(“method. Name”, new Class[] {. . . }, new Object[] {. . . }, “time. Storing. Field”); • No code repetition, less clutter!

Classes in the Reflection API • Class Constructor • Class Field • Class Method

Classes in the Reflection API • Class Constructor • Class Field • Class Method

Getting an Object of type Class • If you have an instance of the

Getting an Object of type Class • If you have an instance of the class: – Class class. Object = instance. Object. get. Class(); • If you know the name of the class at compile time: – Class class. Object = Class. Name. class • If you know the name of the class at run time: – Class. for. Name(“. . . ”); • If you want a primitive type class, and you know the name of the wrapper class at compile time; – Integer. TYPE, Long. TYPE, etc

some methods in the Class class • get. Name() • get. Super. Class() •

some methods in the Class class • get. Name() • get. Super. Class() • get. Component. Type() – [null if !is. Array()] • is. Array() • is. Interface() • is. Primitive() • is. Instance(Object o) • Object new. Instance()

Getting Constructors/Methods/Fields • ask the Class Object for them – – class. Object. get.

Getting Constructors/Methods/Fields • ask the Class Object for them – – class. Object. get. Constructors() class. Object. get. Constructor( Class[] arg. Types) class. Object. get. Declared. Constructors( Class[] arg. Types) • Methods and Fields have analogous getters in class Class. • you can get an array of all the c/m/f in the class, or just one by name, and if you ask for “Declared” it gives you the non-public ones as well.

Objects of Type Method • calling a method dynamically: – Object method. Object. invoke(Object

Objects of Type Method • calling a method dynamically: – Object method. Object. invoke(Object o, Object[] args); • getting info about it: – Class[] get. Parameter. Types() – Class get. Return. Type() – Class[] get. Exception. Types()

Objects of type Field • Object field. Object. get( Object o ); – also

Objects of type Field • Object field. Object. get( Object o ); – also get. Int(Object), get. Boolean(Object), etc. • void field. Object. set( Object o, Object value ); – also set. Int(Object o, int i), etc. • Class field. Object. get. Type() [compile time, of course] • Fields of type int will have Integer. TYPE as the result of get. Type(), and it’s a Class Object.

Objects of type Constructor • Object constructor. Object. new. Instance( Object[] args ) •

Objects of type Constructor • Object constructor. Object. new. Instance( Object[] args ) • Class[] constructor. Object. get. Exception. Types() • Class[] constructor. Object. get. Parameter. Types()

Member Interface • Method, Field, and Constructor classes all extend the Member Interface •

Member Interface • Method, Field, and Constructor classes all extend the Member Interface • Class get. Declaring. Class() • String get. Name() • int get. Modifiers()

Modifier class (static methods) • How do you know if something is static, final,

Modifier class (static methods) • How do you know if something is static, final, etc. ? • int get. Modifiers() [from Member Interface] • • Modifer. is. Static(int) Modifer. is. Final(int) Modifier. is. Protected(int) etc.

Array class (static methods) • Object Array. get(Object array. Object, int i); • void

Array class (static methods) • Object Array. get(Object array. Object, int i); • void Array. set(Object array. Object, int index, Object value) • int Array. get. Length(Object array. Object); • Object new. Instance(Class type, int length) • Object new. Instance(Class type, int[] dimensions)

Reflection Group Task #1 • Fill in example from beginning of lecture: Object time.

Reflection Group Task #1 • Fill in example from beginning of lecture: Object time. Method(String method. To. Call, Class[] arg. Types, Object[] args, String time. To. Update. Field) {. . . Please fill this in!. . . }

Solution to Reflection Group Task 1 Object time. Method(String method. To. Call, Class[] arg.

Solution to Reflection Group Task 1 Object time. Method(String method. To. Call, Class[] arg. Types, Object[] args, String time. To. Update. Field) throws No. Such. Method. Exception, No. Such. Field. Exception, Invocation. Target. Exception, Illegal. Access. Exception { Class c = this. get. Class(); long start. Time = System. current. Time. Millis(); Method m = c. get. Method(method. To. Call, arg. Types); Object return. Value = m. invoke(this, args); long end. Time = System. current. Time. Millis(); Field f = c. get. Field(time. To. Update. Field); f. set. Long(this, f. get. Long(this) + (end. Time - start. Time)); return. Value; }

Reflection Group Task #2 Fill in the class definition to call get. X methods

Reflection Group Task #2 Fill in the class definition to call get. X methods and print their values in the form: Class. Name property. Name = value import java. lang. reflect. *; public class Property. Value. Finder { final String GET = "get"; public void print. Properties(Object o) { /*fill this in*/ } private Property property. Gotten. By(Method method) { /*fill this in*/} private boolean is. Getter(Method method) { /*fill this in*/ } public class Property { String name; Class type; Object value; public Property(String name, Class type) { this. name = name; this. type = type; } public void set. Value(Object value) { this. value = value; } public String to. String() { return type+" "+name+" = "+value; } } }

Group Task #2 Solutions private boolean is. Getter(Method m) { boolean name. OK =

Group Task #2 Solutions private boolean is. Getter(Method m) { boolean name. OK = m. get. Name(). starts. With(GET); boolean no. Args = m. get. Parameter. Types(). length == 0; boolean non. VOID = m. get. Return. Type() != Void. TYPE; return name. OK && no. Args && non. VOID; } private Property property. Gotten. By(Method m) { if (!is. Getter(m)) return null; Class property. Type = m. get. Return. Type(); String property. Name = m. get. Name(). substring(GET. length()); return new Property(property. Name, property. Type); }

Group Task #2 Solutions public void print. Properties(Object o) { Class o. Class =

Group Task #2 Solutions public void print. Properties(Object o) { Class o. Class = o. get. Class(); Method[] methods = o. Class. get. Methods(); for (int i = 0; i < methods. length; i++) { Method m = methods[i]; if (is. Getter(m)) { try { Object value = m. invoke(o, new Object[0]); Property p = property. Gotten. By(m); p. set. Value(value); System. out. println(p); } catch (Illegal. Access. Exception e) { throw new Runtime. Exception(); //programmer error } catch (Illegal. Argument. Exception e) { throw new Runtime. Exception(); //programmer error } catch (Invocation. Target. Exception e) { throw new Runtime. Exception(); //programmer error } }

Discussion Topic • Restriction to Serializer project: • I must promise that the Objects

Discussion Topic • Restriction to Serializer project: • I must promise that the Objects I test your code on will have a no-args constructor that: – sets the value of any final variables that are not set in the class definition – does not throw any exceptions. • If you could add functionality to the Reflection API, how would you fix this without compromising the integrity of the keyword final? • Work in teams, and then we’ll exchange ideas. • Great, now go start a JSR (Java Specification Request)! – http: //www. jcp. org/en/participation/membership