簡體   English   中英

Java 8:反射Field.get()嘗試捕獲錯誤

[英]Java 8: Reflection Field.get() try-catch error

問題

我在Eclipse中收到一條錯誤消息,指出我對Field.get(Object)調用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());

Main.java

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

Item.java

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

實體.java

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現在有點愚蠢(可能有一個打開的錯誤)。

你在這里有一個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主體是一個簡單的表達式而不是一個塊時,似乎會發生這種情況。

您需要處理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());
        } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM