I am receiving an error in Eclipse stating that I have an unhandled exception with my call to Field.get(Object)
. When I wrap the code in the recommended try-catch, the error persists. I assume that I have to wrap the parameter, in the get()
method, with a try-catch. Is this possible?
Unhandled exception type IllegalAccessException
Line in question:
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;
}
}
Eclipse is kind of stupid right now (there's probably a bug open).
You have a lambda expression in here
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
Field#get(Object)
is declared as throwing a checked exception. But Function#apply(Object)
, which is the functional interface method you're implementing, does not. Eclipse is stupid in that it recommends that you wrap the statement in a try block, but it adds the try block around the whole thing
try {
return list.stream().map(e -> fieldType.cast(f.get(e))).collect(Collectors.toList());
} catch (Exception e) {
}
when in reality it should be adding it to the body of the 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());
This seems to happen when your lambda body is a simple expression rather than a block.
You need to handle IllegalAccessException
which can be thrown as a result of fieldType.cast(f.get(e))
. You can surround the code within 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());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.