YAML 读取转换异常

YAML Read casts exception

读取文件时出错

Exception in thread "main" java.lang.ClassCastException: java.lang.String can not be cast to java.util.ArrayList.

为什么没有发生?我正在使用 YamlSnake 库

Person.java:

public class Person
{

    int id;
    String fname;
    String lname;
    int age;

    public Person(int id, String fname, String lname, int age)
    {

        this.id = id;
        this.fname = fname;
        this.lname = lname;
        this.age = age;
    }
}

yaml.java:

@Override
public ArrayList<Person> Read() {

    ArrayList<Person> pp = new ArrayList<Person>();
    try 
    {
        FileReader fr = new FileReader("d:\Person.yml");
        BufferedReader br = new BufferedReader(fr);
        String str=br.readLine();
        Yaml yml = new Yaml();
        pp=(ArrayList<Person>) yml.load(str);
        fr.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return pp;
}

Person.yaml:

-id:2 fname:uu lname:uu age:45

您的 YAML 语法有误。在块映射中,每行只允许一个键。此外,-: 之后必须有一个 space 才能将它们识别为 YAML 特殊字符。尝试:

- id: 2
  fname: uu
  lname: uu
  age: 45

如果想保持一行,可以用流程图代替:

- {id: 2, fname: uu, lname: uu, age: 45 }

现在第二个问题是类型擦除。你不能告诉 SnakeYaml 将 YAML 序列加载到 ArrayList<Person> 中,因为在运行时,即使你告诉 SnakeYaml 你想要一个 ArrayList,也无法确定通用参数 Person。然而,SnakeYaml 确实提供了克服该限制的可能性 - 唉,它需要你改变你的 YAML。

让它成为您的 YAML:

persons:
- id: 2
  fname: uu
  lname: uu
  age:45

请注意,我放置了一个 YAML 映射作为根元素,它只包含一个键 persons,其值为原始 YAML。

现在,在 Java 中,声明一个匹配此根元素的 class:

class Root {
    List<Person> persons;
}

和以前一样,类型擦除阻止 SnakeYaml 在运行时自动确定 persons 类型的泛型参数。但是现在,我们可以使用 TypeDescription 来携带该信息。这是代码:

@Override
public List<Person> Read() {
    Constructor c = new Constructor(Root.class);
    TypeDescription td = new TypeDescription(Root.class);
    td.putListPropertyType("persons", Person.class);
    c.addTypeDescription(td);
    Yaml yaml = new Yaml(c);

    try  {
        FileReader fr = new FileReader("d:\Person.yml");
        Root r = yaml.loadAs(fr, Root.class);
        fr.close();
        return r.persons;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return Collections.<Person>emptyList();
}

注意上面代码中的错误,我没有测试它。