为什么mybatis的MetaObject类不支持“[0]”这样的路径?

问题描述 投票:0回答:1

我正在阅读mybatis代码,我发现MetaObject是一个非常重要的类。 我们用它来访问对象的属性(甚至是嵌套属性)。 如果我们有一个像这样的对象:

{
  "a": {
      "b":[1,2,3]
  }
}

当我们想要获取b[0]的值时; 我们总是使用这样的形式:

metaObject.getValue("a.b[0]");

一切都很好。

但是,如果我有这样的收藏:

// create a single element list: [1]
MetaObject mo = MetaObject.forObject(
      new ArrayList<String>() {{add("1");}},
      new DefaultObjectFactory(),
      new DefaultObjectWrapperFactory(),
      new DefaultReflectorFactory()
);

// If I want get the element of collection.
// It will cause an error.
System.out.println(metaObject1.getValue("[0]"));

// Because the CollectionWrapper is not implements the 'get' method.
// the code is following:
public Object get(PropertyTokenizer prop) {
  throw new UnsupportedOperationException();
}

所以,我不明白为什么我们不支持这种方式来查找像“[0]”这样的集合元素。

现在我们只支持从外部对象(如“b[0]”)访问集合的元素,而b是对象的属性。

有人知道吗?

mybatis
1个回答
0
投票

核心原因是“java.util.Collection不保证顺序,不允许通过索引访问。”。

当我们访问bean或map的集合属性时,它将被转换为Array或List。

如果访问的集合属性不是Array或List,我们将抛出ReflectionException。

所以我们不用担心集合的顺序。

核心代码如下:

protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
    if (collection instanceof Map) {
      return ((Map) collection).get(prop.getIndex());
    } else {
      int i = Integer.parseInt(prop.getIndex());
      if (collection instanceof List) {
        return ((List) collection).get(i);
      } else if (collection instanceof Object[]) {
        return ((Object[]) collection)[i];
      } else if (collection instanceof char[]) {
        return ((char[]) collection)[i];
      } else if (collection instanceof boolean[]) {
        return ((boolean[]) collection)[i];
      } else if (collection instanceof byte[]) {
        return ((byte[]) collection)[i];
      } else if (collection instanceof double[]) {
        return ((double[]) collection)[i];
      } else if (collection instanceof float[]) {
        return ((float[]) collection)[i];
      } else if (collection instanceof int[]) {
        return ((int[]) collection)[i];
      } else if (collection instanceof long[]) {
        return ((long[]) collection)[i];
      } else if (collection instanceof short[]) {
        return ((short[]) collection)[i];
      } else {
        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
      }
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.