我可以使这个java pluck()方法更安全吗?

its*_*dok 6 java generics reflection

我写了这个实用功能:

public static <T> List<T> pluck(String fieldName, List list) 
        throws NoSuchFieldException, IllegalAccessException {
    if (list.isEmpty()) {
        return new ArrayList<T>();
    }
    Class c = list.get(0).getClass();
    Field f = c.getField(fieldName);
    ArrayList<T> result = Lists.newArrayList();
    for (Object object : list) {
        result.add((T) f.get(object));
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

我从underscore.js复制了这个想法.用例是:

ArrayList<Person> people = new ArrayList<Person>;
people.add(new Person("Alice", "Applebee"));
people.add(new Person("Bob", "Bedmington"));
people.add(new Person("Charlie", "Chang"));

List<String> firstNames = pluck("firstName", people);
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果调用者输入的类型错误,则在调用者尝试从列表中获取对象之前不会抛出任何异常.理想情况下,我想ClassCastExceptionpluck方法本身抛出一个.但是,我没有看到在运行时访问列表类型的方法.

有没有一些技巧我可以用来确保调用者没有一个无效的列表?


编辑:所以使用我得到的反馈,一个安全的实现将是:

public static <T,F> List<F> pluck(String fieldName, Class<F> fieldType, 
        List<T> list, Class<T> listType) 
        throws NoSuchFieldException, IllegalAccessException {
    Field f = listType.getField(fieldName);
    ArrayList<F> result = new ArrayList<F>();
    for (T element : list) {
        result.add(fieldType.cast(f.get(element)));
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

但实际上lambdaj似乎做了我想要的,所以我想我会用它.谢谢迈克!

免责声明: LambdaJ(@GoogleCode | @GitHub) - 自JDK8(JSR 335,JEP 126)发布以来,该项目不再维护.

Bhe*_*ung 2

您可以将签名更改为如下:

public static <T, F> List<F> pluck(String fieldName, Class<F> fieldType, 
                                           List<T> list, Class<T> listType)
Run Code Online (Sandbox Code Playgroud)

您有列表类型和字段类型。