是否有开源Java反射实用程序或JAR?

是否有开源Java反射实用程序或JAR?,java,reflection,Java,Reflection,是否有任何开源实用程序或jar用于处理java中的反射 我正在动态地将方法传递给一个类,我希望获取返回值 例如: class Department { String name ; Employee[] employees; public void setName(String name) { this.name = name; } public String getName() { return name; }

是否有任何开源实用程序或jar用于处理java中的反射

我正在动态地将方法传递给一个类,我希望获取返回值

例如:

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

    public String getName() {
        return name;
    }

    public  Employee[] getEmployes() {
        return employees;

    }
}
我希望将所有员工打印到控制台输出中,但在运行时得到它,如下所示:

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.
Employee[] employees = on(department).call("getEmployees").get();

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

是否有任何基于反射的开源软件可以容纳这样的内容?

您可以使用apache beanutils:

您可以按照其他人的建议使用一些第三方库,也可以自己手动完成,这并不难。以下示例应说明可以采取的方法:


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

除了使用ApacheBeanutils或直接使用
java.lang.reflect
API之外,正如其他人所建议的,您还可以使用它,我创建它是为了减少在java中使用反射的冗长性。您的示例可以这样实现:

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.
Employee[] employees = on(department).call("getEmployees").get();

for (Employee employee : employees) {
  Street street = on(employee).call("getAddress").call("getStreet").get();
  System.out.println(street);
}
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);
}
此外,jOOR还以更方便的方式包装了
java.lang.reflect.Proxy
功能:

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

当我看到这种东西时,它总是敲响设计的警钟

也就是说,我通常认为,如果不能以更工程化的方式解决这类问题,JXPath()是最合理的解决方案:

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

}
import org.apache.commons.jxpath.JXPathContext;
导入java.util.ArrayList;
导入java.util.Iterator;
导入java.util.List;
/**
*/
公共类JXPather{
公共静态void main(字符串[]args){
部门d=新部门();
d、 添加(新员工(新地址(“a”));
d、 添加(新员工(新地址(“b”));
d、 添加(新员工(新地址(“c”));
d、 添加(新员工(新地址(“def”));
JXPathContext=JXPathContext.newContext(d);
//通过迭代访问匹配的xpath对象
for(Iterator Iterator=context.iterate(“/employees/address/street”);Iterator.hasNext();){
System.out.println(iterator.next());
}
//或者直接通过标准xpath表达式
System.out.println(“第三个雇员的街道是:”+context.getValue(“/employees[3]/address/street”);
//支持大多数(或全部)xpath表达式
for(Iterator Iterator=context.iterate(“/employees/address/street[string length(.)>11]”);Iterator.hasNext();){
System.out.println(“街道长度大于11厘米:+iterator.next());
}
}
静态公共课系{
List employees=new ArrayList();
公开名单{
返回员工;
}
}
静态公共类雇员{
地址;
雇员(地址){
this.address=地址;
}
公共广播getAddress(){
回信地址;
}
}
静态公共类地址{
弦街;;
地址(字符串街){
这条街;
}
公共字符串getStreet(){
返回街;;
}
}
}

getEmployes()
是否返回数组?在
[]
上没有方法
getAddress()
。这是一种非常有趣的方法。直到现在我才知道JXPath。看起来很漂亮!看起来很好,但是您确定在get()方法中泛化丢弃是个好主意吗?我假设签名是
T get()
,这可能会比呼叫站点上一个好的诚实演员带来更多的麻烦。@MartinProbst:是的,关于签名你是对的。我不认为这是个坏主意
java.util.Collections
有两个类似的情况…@LukasEder:java.util.Collections中的情况只涉及返回集合的泛型类型,它在运行时不存在(因为擦除)。由于返回的集合是不可变的,这永远不会导致错误,而且差异甚至不可观察,因此强制转换总是安全的。@MartinProbst:Hmm,你是对的。我没有这样想过。我也在研究Collections.reverseOrder(),但最终,反向排序比较器也可以安全地处理任何类型。我想,我会更正jOOR API