srinannapa
srinannapa

Reputation: 3207

Are there any open source Java reflection utilities or jars?

Is there any open source utility or jar for handling reflection in java?

I am passing methods Dynamically to a class and I would like to fetch the return value.

For Example:

class Department {
    String name ;
    Employee[] employees;
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public  Employee[] getEmployes() {
        return employees;

    }
}

I would like to print all the employees to the console output but instead getting it at run-time like this:

Department dept = new Department();
// add employees..

getEmployeeNames(dept,"getEmployees.getAddress.getStreet");
// So the user says they want employee street, but we don't know that
// until run-tme.

Is there any opensource on reflection to accommodate something like this?

Upvotes: 9

Views: 4989

Answers (4)

Lukas Eder
Lukas Eder

Reputation: 220842

Apart from using Apache BeanUtils or using the java.lang.reflect API directly, as others suggested, you could also use jOOR, which I created to decrease the verbosity of using reflection in Java. Your example could then be implemented like this:

Employee[] employees = on(department).call("getEmployees").get();

for (Employee employee : employees) {
  Street street = on(employee).call("getAddress").call("getStreet").get();
  System.out.println(street);
}

The same example with normal reflection in Java:

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);
}

Also, jOOR wraps the java.lang.reflect.Proxy functionality in a more convenient way:

interface StringProxy {
  String mySubString(int beginIndex);
}

// You can easily create a proxy of a custom type to a jOOR-wrapped object
String substring = on("java.lang.String")
                    .create("Hello World")
                    .as(StringProxy.class)
                    .mySubString(6);

Upvotes: 20

user467257
user467257

Reputation: 1742

This kind of thing always rings design alarm bells when I see it.

That being said, I usually think that JXPath ( http://commons.apache.org/jxpath/users-guide.html ) is the most reasonable solution for that type of problem if it can't be solved in a more engineered way:

import org.apache.commons.jxpath.JXPathContext;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 */
public class JXPather {
    public static void main(String[] args) {
        Department d = new Department();
        d.employees.add(new Employee(new Address("wherever a")));
        d.employees.add(new Employee(new Address("wherever b")));
        d.employees.add(new Employee(new Address("wherever c")));
        d.employees.add(new Employee(new Address("wherever def")));

        JXPathContext context = JXPathContext.newContext(d);
        // access matched xpath objects by iterating over them
        for (Iterator iterator = context.iterate("/employees/address/street"); iterator.hasNext();) {
            System.out.println(iterator.next());
        }

        // or directly via standard xpath expressions

        System.out.println("street of third employee is: "+context.getValue("/employees[3]/address/street"));

        // supports most (or all ?) xpath expressions

        for (Iterator iterator = context.iterate("/employees/address/street[string-length(.) > 11]"); iterator.hasNext();) {
            System.out.println("street length longer than 11 c'ars:"+iterator.next());
        }
    }

    static public class Department {
        List<Employee> employees = new ArrayList<Employee>();
        public List<Employee> getEmployees() {
            return employees;
        }
    }

    static public class Employee {
        Address address;
        Employee(Address address) {
            this.address = address;
        }
        public Address getAddress() {
            return address;
        }

    }

    static public class Address {
        String street;
        Address(String street) {
            this.street = street;
        }
        public String getStreet() {
            return street;
        }
    }

}

Upvotes: 5

JiP
JiP

Reputation: 3258

You can use some third-party library as others suggest or can do the trick manually yourself, it is not so hard. The following example should illustrate the way one could take:


class Department {
  Integer[] employees;
  public void setEmployes(Integer[] employees) { this.employees = employees; }
  public Integer[] getEmployees() { return employees; }
}

Department dept = new Department();
dept.setEmployes(new Integer[] {1, 2, 3});
Method mEmploees = Department.class.getMethod("getEmployees", new Class[] {});
Object o = mEmploees.invoke(dept, new Object[] {});
Integer[] employees = (Integer[])o;
System.out.println(employees[0].doubleValue());;

Upvotes: 1

Murat HAZER
Murat HAZER

Reputation: 81

you can use apache beanutils: http://commons.apache.org/beanutils/

Upvotes: 1

Related Questions