IWETHEY v. 0.3.0 | TODO
1,095 registered users | 0 active users | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New Sure - Ever tried BeanShell?
You can lookup and call any method on any object you like in Java - you just have to jump through hoops to do it.

Suppose you have an object - you don't know what class it is but you expect it to implement int add(int, int); You could lookup and invoke the method like this:

import java.lang.reflect.*;
...
Class cls = object.getClass(); // get the object's class
Class[] argTypes = { Integer.class, Integer.class }; // specify the types of the methods arguments
Method add = cls.getMethod("add",argTypes); // this is an objectified function pointer
Object[] args = { new Integer(5); new Integer(7); } // pack up the arguments in object wrappers in an array
int result = ((Integer) add.invoke(object,args)).intValue(); // call the thing and unwrap the result

It doesn't matter what class object is, as long as you can find a method add taking a couple of ints then you can arrange to call it. This is how BeanShell works. BeanShell is a scripting language that sits atop Java and uses reflection everywhere. Variables need not be declared or typed. The above code is the equivalent of

result = object.add(5,7);

in BeanShell. They could have made the compiler interpret invocations on parameterized types this way. They would have taken a performance hit though. In Java 1.3 I benchmarked the time required to call a method this way vs a regular method call and it was 50 times slower.

I have this nifty utility that uses reflection to get values from a path. You can do something like:

Object value = PropertyPath.valueForPath(object,"user.address.zip");

This is handy for doing GUI's. It is roughly the equivalent of user.getAddress().getZip(), but if address is null you'll get an exception using the latter case, but PropertyPath will just swallow all exceptions and give you null if it can't traverse the path for some reason. It does some neat tricks flattening collections too but I digress.

Doing more benchmarking, I found the bulk of the time being wasted was in class.getMethod(...); It turns out that doing method.invoke(object,args) is about 1.5 times the speed of object.add(int,int); This is quite decent. PropertyPath caches method lookups and builds a cache of AccessPaths indexed by class. So PropertyPath is about 1.6 times the speed of regular method calls. There's no reason the compiler couldn't use a similar technique and cache Method lookups in local static variables. The performance difference would have been minor considering the gain in flexibility. But I can just hear the justification (we wanted users of generics to incur no performance hits). Fine - doing nothing costs nothing. But there's no gain either.

And why is method lookup performance so bad? Because reflection was added as an afterthought and its use is officially "discouraged" because it circumvents the type system which runs counter to the Java philosophy.


The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
Collapse Edited by tuberculosis March 14, 2004, 01:17:09 AM EST
Sure - Ever tried BeanShell?
You can lookup and call any method on any object you like in Java - you just have to jump through hoops to do it.

Suppose you have an object - you don't know what class it is but you expect it to implement int add(int, int); You could lookup and invoke the method like this:

import java.lang.reflect.*;
...
Class cls = object.getClass();
Class[] argTypes = { Integer.class, Integer.class };
Method add = cls.getMethod("add",argTypes);
Object[] args = { new Integer(5); new Integer(7); }
int result = ((Integer) add.invoke(object,args)).intValue();

It doesn't matter what class object is, as long as you can find a method add taking a couple of ints then you can arrange to call it. This is how BeanShell works. BeanShell is a scripting language that sits atop Java and uses reflection everywhere. Variables need not be declared or typed. The above code is the equivalent of

result = object.add(5,7);

in BeanShell. They could have made the compiler interpret invocations on parameterized types this way. They would have taken a performance hit though. In Java 1.3 I benchmarked the time required to call a method this way vs a regular method call and it was 50 times slower.

I have this nifty utility that uses reflection to get values from a path. You can do something like:

Object value = PropertyPath.valueForPath(object,"user.address.zip");

This is handy for doing GUI's. It is roughly the equivalent of user.getAddress().getZip(), but if address is null you'll get an exception using the latter case, but PropertyPath will just swallow all exceptions and give you null if it can't traverse the path for some reason. It does some neat tricks flattening collections too but I digress.

Doing more benchmarking, I found the bulk of the time being wasted was in class.getMethod(...); It turns out that doing method.invoke(object,args) is about 1.5 times the speed of object.add(int,int); This is quite decent. PropertyPath caches method lookups and builds a cache of AccessPaths indexed by class. So PropertyPath is about 1.6 times the speed of regular method calls. There's no reason the compiler couldn't use a similar technique and cache Method lookups in local static variables. The performance difference would have been minor considering the gain in flexibility. But I can just hear the justification (we wanted users of generics to incur no performance hits). Fine - doing nothing costs nothing. But there's no gain either.

And why is method lookup performance so bad? Because reflection was added as an afterthought and its use is officially "discouraged" because it circumvents the type system which runs counter to the Java philosophy.



The tree of research must from time to time be refreshed with the blood of bean counters.
     -- Alan Kay
     Bruce Eckel on Java's generics - (ben_tilly) - (14)
         ObAPL plug - (deSitter)
         I enjoyed the follow-up more :) - (FuManChu)
         They're mostly about eliminating casting in collections - (tuberculosis) - (11)
             as a non jhead or any recent programmer - (boxley) - (1)
                 Sure - Ever tried BeanShell? - (tuberculosis)
             That was pretty much Bruce Eckel's point of view - (ben_tilly) - (7)
                 B&D is simpler - why complicate? - (deSitter) - (5)
                     Why isn't Forth ideal? - (ben_tilly) - (2)
                         Re: Why isn't Forth ideal? - (deSitter) - (1)
                             Yes, but never from those who designed it. ;) -NT - (FuManChu)
                     Bondage & Discipline? -NT - (tuberculosis) - (1)
                         Yes, it's stupid vacuous X-speak - (deSitter)
                 Yes - he no longer "Thinks in Java" - (tuberculosis)
             The real way to do generics would have been ... - (bluke)

This massage will self-rubout within a trice.
87 ms