如何从地图中的内容对象获取属性类型

时间:2015-12-11 11:39:27

标签: java reflection

下一个代码是对我的代码的改编,我希望它可以帮助你。

Order.java

public class Order {
    ...
    private Long id = ...;
    private Map<Integer, Item> items = new LinkedHashMap<Integer, Item>();
    ...
}

Item.java

public abstract class Item {

    public abstract Object getValue();
    public abstract void setValue(Object value);

}

ItemInt.java

public class ItemInt extends Item {

    private Integer number;

    @Override
    public Integer getValue() {
        return number; 
    }

    @Override
    public void setValue(Object value) {
        number = (Integer) value;
    }
}

ItemFloat.java

public class ItemFloat extends Item {

    private Float number;

    @Override
    public Float getValue() {
        return number; 
    }

    @Override
    public void setValue(Object value) {
        number = (Float) value;
    }
}

我试图使用下一个字符串"items[2].value"获取属性类型,但它不起作用。我该怎么做?结果为intfloat

Order order = ...;
....
final Class<?> clazz = new PropertyUtilsBean().getPropertyType(order, "items[2].value");

另外,我必须使用相同的方法动态访问其他类型的对象。例如:

final Class<?> clazz = new PropertyUtilsBean().getPropertyType(order, "id");

我真正的问题是如何构建此String以访问地图中的内容对象。

2 个答案:

答案 0 :(得分:0)

好吧,你必须做items.get(<value>)才会给你这个项目。但是,这可能是ItemInt或ItemFloat。所以,这就是我们如何获得该项目:

Item item = items.get(123);
if(item instanceof ItemInt){
//do something
}else if(item instanceof ItemFloat){
//do something else
}

这样,我们就能知道项目类型。一旦知道了项目类型,我们就可以将值转换为相应的Object。

或者,如果我们想直接从item获取值(假设Item值总是一个数字,那么我们可以修改

public abstract Object getValue();

public abstract Number getValue();

这样,我们可以直接执行item.getValue()并将其分配给Number实例。

根据新的/已更改的问题进行编辑

我们可以在这里使用List而不是map,因为它自动命令对象,我在上面的例子中看不到Key的使用。因此,更新的Order类将是:

public class Order {
    ...
    private Long id = ...;
    private List<Item> items = new ArrayList<Item>();
    ...
}

现在,要从订单中获取商品价值,我们可以编写如下方法:

public Number getItemValue(Order order, int index) throws IllegalArgumentException{
    if(order.getItems().size() < index){
        throw new IllegalArgumentException("Invalid index.");
    }
    return order.getItems().get(index-1).getValue();
}

如果值不仅仅是数字,我们可以将返回类型更改为Object。希望它有所帮助。

答案 1 :(得分:0)

希望这有帮助

public class Test {

    Map<Integer, Item> items = new LinkedHashMap<Integer, Item>();

    // HashMap have method values(), but not property values.
    public List<Item> getValues() {
        return new ArrayList<Item>(items.values());
    }

    public abstract class Item {

        public abstract Object getValue();

        public abstract void setValue(Object value);

    }

    public class ItemInt extends Item {

        private Integer value;

        public Integer getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = (Integer) value;
        }
    }

    public class ItemFloat extends Item {

        private Float value;

        public Float getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = (Float) value;
        }
    }


    public Test() {

        ItemInt value = new ItemInt();
        value.setValue(1);
        items.put(0, value);


        ItemFloat itemFloat = new ItemFloat();
        itemFloat.setValue(4f);
        items.put(1, itemFloat);

    }

    public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Test test = new Test();

        Object property = new PropertyUtilsBean().getProperty(test, "values[0].value");
        System.err.println("" + property.getClass());
    }

}