我在Eclipse中收到一条错误,指出我对Field.get(Object)
的调用存在未处理的异常。当我将代码包装在推荐的try-catch中时,错误仍然存在。我假设我必须使用try-catch在get()
方法中包装参数。这可能吗?
Unhandled exception type IllegalAccessException
有问题的一行:
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Entity> entities = Arrays.asList(
new Item(0, "Apple"),
new Item(1, "Banana"),
new Item(2, "Grape"),
new Item(3, "Orange")
);
List<Long> ids = null;
try {
ids = pluck("id", Long.class, entities, Entity.class, true);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(ids);
}
public static <E extends Entity> List<Long> pluckIds(List<E> list) {
return list.stream().map(e -> e.getId()).collect(Collectors.toList());
}
public static <T,F> List<F> pluck(String fieldName, Class<F> fieldType,
List<T> list, Class<T> listType, boolean useLambda)
throws NoSuchFieldException, IllegalAccessException,
IllegalArgumentException {
Field f = listType.getDeclaredField(fieldName);
f.setAccessible(true);
if (useLambda) {
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
} else {
List<F> result = new ArrayList<F>();
for (T element : list) {
result.add(fieldType.cast(f.get(element)));
}
return result;
}
}
}
public class Item extends Entity {
private String name;
public Item(long id, String name) {
super(id);
this.setName(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public abstract class Entity {
private long id;
public Entity(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
答案 0 :(得分:2)
Eclipse现在有点愚蠢(可能有一个错误)。
你在这里有一个lambda表达式
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
Field#get(Object)
被声明为抛出已检查的异常。但Function#apply(Object)
,即你正在实现的功能接口方法,却没有。 Eclipse是愚蠢的,因为它建议你将语句包装在try块中,但它会在整个事件中添加try块
try {
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
} catch (Exception e) {
}
实际上它应该将它添加到lambda的主体
return list.stream().map(e -> {
try {
return fieldType.cast(f.get(e));
} catch (Exception e) {
return /* something else */ null; // or throw an unchecked exception
}
}).collect(Collectors.toList());
当你的lambda主体是一个简单的表达式而不是一个块时,这似乎就会发生。
答案 1 :(得分:1)
您需要处理因IllegalAccessException
而可能抛出的fieldType.cast(f.get(e))
。您可以在try/catch
if (useLambda) {
return list.stream().map(e -> {
try {
return fieldType.cast(f.get(e));
} catch (IllegalAccessException e1) {
e1.printStackTrace();
return null;
}
}).collect(Collectors.toList());
}