【问题标题】:inherited java ArrayList to JSON继承 java ArrayList 到 JSON
【发布时间】:2018-04-03 18:57:06
【问题描述】:

我有一个覆盖 ArrayList 的类,例如:

public class SkmeList extends ArrayList<SkmeStatement> {
  private static final long serialVersionUID = 1L;
  private int skmeMajor = 0;
  private int skmeMinor = 0;
  private String skmeTable = null;

  public void setTable(String table) {
    System.out.println("Set Table: " + table);
    skmeTable = table;
  }
  public String getTable() {
    return skmeTable;
  }
  public void setMajor(int major) {
    System.out.println("SetMajor: " + major);
    skmeMajor = major;
  }
  public int getMajor() {
    return skmeMajor;
  }
  public void setMinor(int minor) {
    System.out.println("SetMinor: " + minor);
    skmeMinor = minor;
  }
  public int getMinor() {
    return skmeMinor;
  }
}

当我尝试使用 jackson 将此类写入文件甚至字符串时,我只能看到列表内容,我在字符串/文件中看不到任何特定于类的属性,例如 Major 或 minor?我像对待任何其他 java 类一样对待这个类。杰克逊对象映射器中的列表有什么不同吗?

public void WriteJson(SkmeList statements) {
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final ObjectMapper mapper = new ObjectMapper();

    try {
        mapper.writeValue(out, statements);

        final byte[] data = out.toByteArray();
        System.out.println(new String(data));
    }
    catch (IOException ioe) {
        System.out.println("Foo");
    }
}

【问题讨论】:

  • 你不应该扩展 ArrayList。你为什么要这样做?
  • 我为什么不呢?它是一个元素列表,该列表具有列表元素的全局参数。
  • 好吧,一方面,JSON 数组不能有参数。但即使不谈论 JSON,也不应该扩展集合。你应该使用它们。阅读 Josh Bloch 的 Effective Java 以获得详细的解释。
  • Composition over inheritance 是一本好书。
  • 在您的具体情况下,Jackson 可能只是检查某物是否是 List/Map/Set,然后使用接口序列化内容。您可以编写一个自定义序列化程序(或 Jackson 所称的任何内容),但实际上您应该只编写现有类型。

标签: java json arraylist


【解决方案1】:

List 有元素,没有更多的非元素数据。如果您需要更多数据,您需要的不仅仅是列表。

如果你的类的用户关心你添加的任何额外字段,他们已经必须特别对待它。

为了支持composition over inheritance,我建议这门课应该是这样的。

public class SkmeList {
  private final int major;
  private final int minor;
  private final String table;
  private final List<SkmeStatement> statements;

  // ctor, getters, hashCode, equals and toString omitted
}

有了更多关于 Skme 含义的上下文,我们可以使命名更加清晰。

为了更容易推理,该类应该是不可变的,以便在Collection 中安全使用它应该有hashCode()equals(),以及一个toString(),以防它被打印出来/记录/调试。

如果您不想实现所有省略的方法,请考虑 AutoValue:您指定 getter 和工厂方法,其余的会为您生成。

对于你班级的用户来说,几乎是一样的:

SkmeList list = ...
for (SkmeStatement stmt : list) {
   ...

现在变成了

SkmeList list = ...
for (SkmeStatement stmt : list.getStatements()) {
   ...

【讨论】:

    猜你喜欢
    • 2015-01-14
    • 1970-01-01
    • 2015-04-23
    • 2012-10-30
    • 2017-12-27
    • 1970-01-01
    • 2011-03-31
    相关资源
    最近更新 更多