23
Advanced Java Course Reflection

Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

  • View
    223

  • Download
    2

Embed Size (px)

Citation preview

Page 1: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Advanced Java Course

Reflection

Page 2: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What
Page 3: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

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?

Page 4: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Example: WebCrawler timer

• To optimize your WebCrawler, 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?

Page 5: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

How to time an operation?

• Without reflection:int startTime = System.currentTimeMillis();doOperation(...);int endTime = System.currentTimeMillis();int duration = endTime – startTime;

• Problem:Code is repeated every place you want to time an

operation! Not clean at all...

Page 6: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

A better way to time an operation

• Object timeMethod(String methodToCall, Class[] argTypes, Object[] args, String timeToUpdateField) {...}

• timeMethod(“methodName”, new Class[] {...}, new Object[] {...}, “timeStoringField”);

• No code repetition, less clutter!

Page 7: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Classes in the Reflection API

• Class Class

• Class Constructor

• Class Field

• Class Method

Page 8: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What
Page 9: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Getting an Object of type Class

• If you have an instance of the class:– Class classObject = instanceObject.getClass();

• If you know the name of the class at compile time:– Class classObject = ClassName.class

• If you know the name of the class at run time:– Class.forName(“...”);

• If you want a primitive type class, and you know the name of the wrapper class at compile time;– Integer.TYPE, Long.TYPE, etc

Page 10: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

some methods in the Class class

• getName()• getSuperClass()• getComponentType() – [null if !isArray()]

• isArray()• isInterface()• isPrimitive()

• isInstance(Object o)• Object newInstance()

Page 11: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Getting Constructors/Methods/Fields

• ask the Class Object for them– classObject.getConstructors()– classObject.getConstructor( Class[] argTypes)– classObject.getDeclaredConstructors()– classObject.getDeclaredConstructors( Class[] argTypes)

• 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.

Page 12: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Objects of Type Method

• calling a method dynamically:– Object methodObject.invoke(Object o,

Object[] args);

• getting info about it:– Class[] getParameterTypes()– Class getReturnType()– Class[] getExceptionTypes()

Page 13: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Objects of type Field

• Object fieldObject.get( Object o ); – also getInt(Object), getBoolean(Object), etc.

• void fieldObject.set( Object o, Object value );– also setInt(Object o, int i), etc.

• Class fieldObject.getType() [compile time, of course]

• Fields of type int will have Integer.TYPE as the result of getType(), and it’s a Class Object.

Page 14: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Objects of type Constructor

• Object constructorObject.newInstance( Object[] args )

• Class[] constructorObject.getExceptionTypes()

• Class[] constructorObject.getParameterTypes()

Page 15: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Member Interface

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

• Class getDeclaringClass()

• String getName()

• int getModifiers()

Page 16: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Modifier class (static methods)

• How do you know if something is static, final, etc.?

• int getModifiers() [from Member Interface]

• Modifer.isStatic(int)• Modifer.isFinal(int)• Modifier.isProtected(int)• etc.

Page 17: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Array class (static methods)

• Object Array.get(Object arrayObject, int i);

• void Array.set(Object arrayObject, int index, Object value)

• int Array.getLength(Object arrayObject);

• Object newInstance(Class type, int length)

• Object newInstance(Class type, int[] dimensions)

Page 18: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Reflection Group Task #1

• Fill in example from beginning of lecture:

Object timeMethod(String methodToCall, Class[] argTypes, Object[] args, String timeToUpdateField) {

...

Please fill this in!

...

}

Page 19: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Solution to Reflection Group Task 1 Object timeMethod(String methodToCall, Class[]

argTypes, Object[] args, String timeToUpdateField) throws NoSuchMethodException,

NoSuchFieldException, InvocationTargetException, IllegalAccessException

{ Class c = this.getClass(); long startTime = System.currentTimeMillis(); Method m = c.getMethod(methodToCall, argTypes); Object returnValue = m.invoke(this, args); long endTime = System.currentTimeMillis(); Field f = c.getField(timeToUpdateField); f.setLong(this, f.getLong(this) + (endTime - startTime)); return returnValue; }

Page 20: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Reflection Group Task #2Fill in the class definition to call all getX methods and print their values in the form:ClassName propertyName = value

import java.lang.reflect.*;public class PropertyValueFinder { final String GET = "get"; public void printProperties(Object o) { /*fill this in*/ } private Property propertyGottenBy(Method method) { /*fill this in*/} private boolean isGetter(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 setValue(Object value) { this.value = value; } public String toString() { return type+" "+name+" = "+value; } }}

Page 21: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Group Task #2 Solutions

private boolean isGetter(Method m) { boolean nameOK = m.getName().startsWith(GET); boolean noArgs = m.getParameterTypes().length == 0; boolean nonVOID = m.getReturnType() != Void.TYPE; return nameOK && noArgs && nonVOID; }

private Property propertyGottenBy(Method m) { if (!isGetter(m)) return null; Class propertyType = m.getReturnType(); String propertyName =

m.getName().substring(GET.length()); return new Property(propertyName, propertyType); }

Page 22: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

Group Task #2 Solutionspublic void printProperties(Object o) { Class oClass = o.getClass(); Method[] methods = oClass.getMethods(); for (int i = 0; i < methods.length; i++) { Method m = methods[i]; if (isGetter(m)) { try { Object value = m.invoke(o, new Object[0]); Property p = propertyGottenBy(m); p.setValue(value); System.out.println(p); } catch (IllegalAccessException e) { throw new RuntimeException(); //programmer error } catch (IllegalArgumentException e) { throw new RuntimeException(); //programmer error } catch (InvocationTargetException e) { throw new RuntimeException(); //programmer error } } } }

Page 23: Advanced Java Course Reflection. Reflection API What if you want to access information not just about the Object, but about that Object’s Class? What

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