Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 253
srinannapa Avatar asked Dec 08 '10 07:12

srinannapa


4 Answers

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);
like image 150
Lukas Eder Avatar answered Oct 27 '22 05:10

Lukas Eder


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

}
like image 33
user467257 Avatar answered Oct 27 '22 05:10

user467257


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

like image 31
Murat HAZER Avatar answered Oct 27 '22 06:10

Murat HAZER


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

like image 45
Jiri Patera Avatar answered Oct 27 '22 06:10

Jiri Patera