Reflection in Java really feels awkward. The java.lang.reflect API is very powerful and complete, and in that sense also very verbose. Unlike in most scripting languages, there is no convenient way to access methods and fields dynamically using reflection. By convenient, I mean things like this
// PHP
$method = 'my_method';
$field = 'my_field';
// Dynamically call a method
$object->$method();
// Dynamically access a field
$object->$field;
Or even better
// JavaScript
var method = 'my_method';
var field = 'my_field';
// Dynamically call a function
object[method]();
// Dynamically access a field
object[field];
For us Java guys, this is something we can only dream of. We would write this
String method = "my_method";
String field = "my_field";
// Dynamically call a method
object.getClass().getMethod(method).invoke(object);
// Dynamically access a field
object.getClass().getField(field).get(object);
Obviously, this doesn’t take care of NullPointerExceptions, InvocationTargetExceptions, IllegalAccessExceptions, IllegalArgumentExceptions, SecurityExceptions, primitive types, etc. In an enterprise world, things need to be safe and secure, and the Java architects have thought of all possible problems that could arise when using reflection. But in many cases, we know what we’re doing and we don’t care about most of those features. We’d prefer the less verbose way.
That’s why I have created another sibling in the
jOO* family:
jOOR (Java Object Oriented Reflection). While this is not a killer libary, it might be useful for 1-2 developers out there looking for a simple and fluent solution. Here’s an example I have recently encountered on stack overflow, where jOOR might fit in just perfectly:
// Classic example of reflection usage
try {
Method m1 = department.getClass().getMethod("getEmployees");
Employee employees = (Employee[]) m1.invoke(department);
for (Employee employee : employees) {
Method m2 = employee.getClass().getMethod("getAddress");
Address address = (Address) m2.invoke(employee);
Method m3 = address.getClass().getMethod("getStreet");
Street street = (Street) m3.invoke(address);
System.out.println(street);
}
}
// There are many checked exceptions that you are likely to ignore anyway
catch (Exception ignore) {
// ... or maybe just wrap in your preferred runtime exception:
throw new RuntimeException(e);
}
And the same example using jOOR:
Employee[] employees = on(department).call("getEmployees").get();
for (Employee employee : employees) {
Street street = on(employee).call("getAddress").call("getStreet").get();
System.out.println(street);
}
See the full Stack Overflow question here:
https://stackoverflow.com/questions/4385003/java-reflection-open-source/8672186
Another example:
String world =
on("java.lang.String") // Like Class.forName()
.create("Hello World") // Call the most specific matching constructor
.call("substring", 6) // Call the most specific matching method
.call("toString") // Call toString()
.get() // Get the wrapped object, in this case a String
Get jOOR for free here:
https://code.google.com/p/joor/Like this:
Like Loading...
Published by lukaseder
I made jOOQ
View all posts by lukaseder
Having a jOOQ generated table, I need to marry in a web service which can pass in those values. Instead of statically calling and checking for each of the field names in the database, is it possible to query the name and type annotations that jOOQ is generating to make this more dynamic?
Hmm, jOOQ’s
Schema
type has agetTables()
method, andTables
themselves havefields()
methods, which might be useful to discover this sort of meta data. Is that what you had in mind?