• No results found

Invocation Handlers

In document Advanced Java Programming by Uttam Roy (Page 172-177)

G eneric P roGramminG

148 ADVANCED JAVA PROGRAMMING private void f() {

7.6 DYNAMIC PROXY

7.6.2 Invocation Handlers

Proxy itself is not as important as its behaviour which is provided by an implementation of java.lang.reflect.InvocationHandler. A method invocation on a proxy instance through one of its proxy interfaces will be dispatched to the invoke() method of the instance’s invocation handler. The prototype of this method looks like this:

Object invoke(Object proxy, Method method, Object[] args)

It takes three parameters, processes a method invocation on a proxy instance and returns the result. The first parameter is a reference for the proxy instance that the method was invoked on. The second parameter is the Method instance corresponding to the interface method invoked on the proxy instance and the last parameter is an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. This essentially is the place where we implement the functionality of the proxy.

Before creating a proxy instance, let us write such a handler. Our handler simply keeps track of method invocation time. So, it looks like this:

import java.lang.reflect.*;

public class MyLogger implements InvocationHandler { Object target;

public MyLogger(Object t) {target = t;}

public Object invoke(Object proxy,Method m,Object[] args)throws Throwable {

double start = System.nanoTime(); Object o = m.invoke(target, args);

double ellapseTime = System.nanoTime() - start;

System.out.println(m.getName() + "() took "+ellapseTime+" ns"); return o;

} }

Object target;

public MyLogger(Object t) {target = t;}

public Object invoke(Object proxy,Method m,Object[] args)throws Throwable {

double start = System.nanoTime(); Object o = m.invoke(target, args);

double ellapseTime = System.nanoTime() - start;

System.out.println(m.getName() + "() took "+ellapseTime+" ns"); return o;

} }

The invoke() intercepts a method call and notes the current system time. It then wants the method call to pass through. For this, it needs a reference to the real object. Since, invoke() method does not provide any such reference, it is passed to the constructor which saves the reference in target.

Note that the method is called on the target object using reflection. That’s why it works generically for all objects and for all methods. We can now call the one argument constructor that takes an invocation handler to create a proxy instance:

Target o = new Target();

Subject s = (Subject)proxyClass.getConstructor(new Class[]

{ InvocationHandler.class }).newInstance(new Object[] { new MyLogger(o) }); Instead of using the reflection API to access the public constructor, a proxy instance can also be created directly by calling the newProxyInstance() method of Proxy as follows :

Target o = new Target();

Subject s = (Subject)Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new MyLogger(o));

The newProxyInstance() method essentially combines the actions of calling getProxyClass() and invoking the constructor with an invocation handler [Figure 7.3: ].

add() Target Caller Invocation Handler Proxy invoke() invoke()

Figure 7.3: Method invocation with proxy installed

The source code of the caller will finally look like this: import java.lang.reflect.*;

public class Caller {

public static void main(String args[]) throws Exception { Target o = new Target();

Subject s = (Subject)Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new MyLogger(o)); int x = 4, y = 3;

int result = s.add(x,y);

System.out.println("In caller: sent: " + x +" and "+y);

System.out.print("In caller: received("+x+"+"+y+"=): " + result); }

}

A sample output of this program looks like this: In add(): received: 4 and 3

In add(): Sent: 7 add() took 605067.0 ns In caller: sent: 4 and 3 In caller: received(4+3=): 7

REFLECTION 155

7.7 DISADVANTAGE OF REFLECTION

One of the primary drawbacks of reflection is that reflective code gets executed more slowly than their non-reflective counterpart. This happens since reflection involves types that are resolved at run-time, but not at compile time. Moreover, since JVM performs a lot of optimization at compile time, codes that use reflection will remain un-optimized and run slower than those codes which did not use reflection API.

Another drawback of reflection is that it allows us to access information that is usually not allowed in non-reflexive code. For example, reflection allows us to access even class’s private fields and methods that would otherwise remain inaccessible in non-reflective code. This violates the rule of abstraction and could potentially ruin the code or may make it non-portable.

So, it is suggested that reflective codes not be used unless it is unavoidable.

KEYWORDS

Array—A class that provides several static methods to

dynamically create and access Java arrays

Class—A Class object represents a class or an

interface in a Java application

Constructor—A class that provides information about,

and access to, a single constructor

Field—A class that provides information about, and

dynamic access to, a single field

Method—A class that provides information about, and

access to, a single method

Modifier—A class contains 12 static constants one

each modifiers that can be applied on class and its members such as fields, methods and constructors

Proxy—A module that sits in the middle of two or more

communicating parties and can intercept, inspect or even modify the messages being exchanged

Reflection—An API in Java that enables us to

examine and/or modify the properties or behaviour or other elements of an object at run-time

Type—A class that represents the type of field

SUMMARY

The reflection API in Java enables us to examine and/ or modify the properties or behaviour or other elements of an object at run-time.

The foundation of Java reflection API is the class

java.lang.Class. A Class object represents a class or an interface in a Java application. This class provides methods to examine both class level and object level runtime information such as modifiers, fields, methods, constructors etc.

There are numerous ways to create such an object. There are certain other important classes for introspection. One such class is Modifier that contains 12 static constants one for each modifier. A field of a class is represented by the Field class that provides information about, and dynamic access to, a single field. A method of a class is represented by the Method

class that provides information about, and access to, a single method. Since, constructors are special methods, reflection API provides a separate class

Constructor that provides information about, and access to, a single constructor.

The reflection API also allows us to invoke a method (both static and non-static) indirectly. This is done using Method.invoke() method. Reflection also provides facility to analyze code using annotations.

Like methods, reflection also provides APIs to find constructors of a class and obtain information such as its modifiers, parameters, annotations and thrown exceptions etc. Reflection can do more than just simply list fields, methods and constructors. Through reflection, we can even create instances.

In reflection API, an array is represented by the

Array class that provides several static methods to dynamically create and access Java arrays.

One of the important facilities of reflection API is the ability to create proxies dynamically.

One of the primary drawbacks of reflection is that reflective code gets executed more slowly than their non-reflective counterpart. Another drawback of reflection is that it allows us to access information that is usually not allowed in non-reflexive code.

WEB RESOURCES

http://docs.oracle.com/javase/tutorial/ reflect/

Trail: The Reflection API

http://ftp.gwdg.de/pub/languages/java/java. sun.com/jdk1.1/java-reflection.pdf

Java™ Core Reflection API and Specification http://wwwusers.di.uniroma1.it/~parisi/ Risorse/java-reflection-explained-simply- manual-8up.pdf Java Reflection http://www.csd.uoc.gr/~hy252/references/ JavaReflection.pdf

Java Reflection in Action

http://www.kencooney.com/programming/java/ reflection.pdf Java Reflection http://www.java2s.com/Tutorial/Java/0125__ Reflection/Catalog0125__Reflection.htm Java Reflection

EXERCISES

Objective-type Questions

1. Which of these packages contains reflection

classes and interfaces? (a) java.reflection (b) java.reflect (c) java.lang.reflection (d) java.lang.reflect

2. Which of the following is used to get the type of

object represented by “obj”? (a) Classloader.getInstance(obj); (b) obj.getClass().getName(); (c) obj.toString();

(d) new Class.getName(obj);

3. What does the following program segment do?

import java.lang.reflect.Field; MyClass myClass = new MyClass(); try { Class cl=Class.forName(“MyClass”); Field res=cl.getDeclaredField(“count”); res.set(myClass,”5”); } catch(Exception e) {}

(a) The first 5 member variables of myClass are copied to “res”.

(b) The value of myClass.count is set to 5. (c) 5 copies of the myClass object are created. (d) The number of MyClass fields described

in “cl” is set to 5.

4. What is primary class in reflection?

(a) Reflection (c) Class (b) Reflect (d) Primary

5. Which of the following methods on an object is used

to get a Class object representing the object’s type?

(a) getClass() (c) type() (b) getType() (d) class()

6. How do you get a Class object for primitive

types?

(a) [I] (c) 2[I (b) I]] (d) [[I

7. Which of the following returns a Class for an array

of String?

(a) Class.forName(“[LString;”); (b) Class.forName(“java.lang.String;”); (c) Class.forName(“[Ljava.lang.String;”); (d) Class.forName(“[Ljava.lang.String”);

8. The total number of modifiers used for class/

interface, fields, methods and constructors is (a) 10 (c) 12

(b) 11 (d) 13

9. What value does classModifiers() return?

(a) 3103 (c) 3391 (b) 7 (d) 223

10. What value does fieldModifiers() return?

(a) 3103 (c) 3391 (b) 7 (d) 223

11. What value does methodModifiers() return?

(a) 3103 (c) 3391 (b) 7 (d) 223

12. What value does constructorModifiers() return?

(a) 3103 (c) 3391 (b) 7 (d) 223

REFLECTION 157

13. Which of the following methods is used to call a

method using reflection?

(a) call() (c) invoke() (b) callMethod() (d) invokeMethod()

14. Which of the following methods is used to create

an instance of a class?

(a) newObject() (c) createObject() (b) createInstance() (d) newInstance()

15. Which of the following modifiers cannot be used

for a class?

(a) public (c) abstract (b) final (d) volatile

16. Which of the following methods is used when

modifying final fields?

(a) setField() (c) makeAccessible() (b) setAccessible() (d) makeModifiable()

17. Which of the following methods is used to find the

list of interfaces a class implements? (a) getGenericInterfaces() (b) getInterfaces() (c) findGenericInterfaces() (d) interfaces()

18. Which of the following classes represents an

invocation handler?

(a) java.reflect.InvocationHandler (b) java.InvocationHandler

(c) java.lang.reflect.InvocationHandler (d) java.lang.reflect.Handler

19. Which of the following methods is used to create

a dynamic proxy? (a) getProxyInstance() (b) getProxy()

(c) createProxyClass() (d) getProxyClass()

20. A dynamic proxy is an instance of

(a) java.lang.reflect.DynamicProxy (b) java.reflect.Proxy

(c) java.lang.reflect.Proxy (d) java.Proxy

21. Which of the following is used to create an

instance of an array using reflection? (a) Array.newInstance()

(b) Array.instance() (c) Array.createArray() (d) Array.createInstance()

Subjective-type Questions

1. Write the mangled names that represent a two-

dimensional array.

2. Write the names of some popular software where

Java reflection is used.

3. How can you construct an object of a given class

using reflection?

4. Write the different ways with their relative merits

and demerits to get the Class object?

5. What is the primary purpose of Modifier class? 6. Using reflection, how can you tell if a member is

public or private?

7. How will you to retrieve modifier’s information of

a class

8. There is no explicit constant which corresponds

to “package” access. So, how will you identify it?

9. Write some of the methods that are used to get

information about a class.

10. Write a program that finds and displays inheritance

hierarchy of a specified class.

11. What is the difference between getDeclaraedFields()

and getFields()?

12. Write a program that shows all public fields of a

specified class.

13. Explain how you will modify final fields.

14. Provide a simple example of object reflection in

Java.

15. Is Java reflection slow and/or expensive?

What are some of the drawbacks of reflection in Java?

In document Advanced Java Programming by Uttam Roy (Page 172-177)