如何获取我的对象的特定属性?

use*_*315 3 java reflection

假设我有这门课.

class People {
    private String name;
    private int age;
    /** other stuff constructor / getters / setters / etc. **/
}
Run Code Online (Sandbox Code Playgroud)

让我们说我有这个清单:

List<People> people = Arrays.asList(new People("Mark", 21), new People("Bob",17), new People("Alex", 22));
Run Code Online (Sandbox Code Playgroud)

现在我希望能够获得List特定属性的所有用户.

使用Java 8,我可以创建一个接受我想要的函数的方法:

public static <X, Y> List<Y> processElements(Iterable<X> source, Function <X, Y> mapper) {
    List<Y> l = new ArrayList<>();
    for (X p : source) 
        l.add(mapper.apply(p));
    return l;
}
Run Code Online (Sandbox Code Playgroud)

然后我将能够执行一些调用:

List<String> listNames = processElements(people, p -> p.getName()); 
List<Integer> listAges = processElements(people, p -> p.getAge()); 
Run Code Online (Sandbox Code Playgroud)

然而,这在Java 7中是不可能的(我知道它存在于Guava中,但我只想使用JDK来提出解决方案).

这是我用反射得到的:

public static List<Object> processElements(List<People> l, String fieldName) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
        Field field = People.class.getDeclaredField(fieldName);
        field.setAccessible(true);
        List<Object> list = new ArrayList<>();
        for(People p : l){
            list.add(field.get(p));
        }
        field.setAccessible(false);
        return list;
}
Run Code Online (Sandbox Code Playgroud)

现在我可以做一些List<Object> listNames = processElements(people, "name");非常有效的事情.

但我觉得不舒服:

  1. 我得到了一个 List<Object>
  2. 每当我使用反射时,我总觉得它存在一个更好的实现而不使用它
  3. 使用field.setAccessible(true);不是很安全

所以我的问题是:

  1. 是否可以在不使用JDK反射(不使用Guava或Functional Java)的情况下执行相同的操作?
  2. 如何根据我作为参数传递给我的方法的字段类型获取String或Integer列表?

谢谢

Sot*_*lis 6

您可以使用Java 7的匿名类完成与Java 8相同的操作

public static <X, Y> List<Y> processElements(Iterable<X> source, Function <X, Y> mapper) {
    List<Y> l = new ArrayList<>();
    for (X p : source) 
        l.add(mapper.apply(p));
    return l;
}

List<String> listNames = processElements(people, new Function<People, String>() {
    public String apply(People person) {
        return person.getName();
    }
}); 
Run Code Online (Sandbox Code Playgroud)