0

I am working on a little todolist-program and i'm getting a weird bug that i never had before. I have 4 classes: 1 POJO class that contains the todo-data:

public class Todo implements Comparable {
  private String title;
  private String task;
  private boolean done;

  public Todo(String title, String task) {
    this.title = title;
    this.task = task;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String newTitle) {
    title = newTitle;
  }

  public String getTask() {
    return task;
  }

  public void setTask(String newTask) {
    task = newTask;
  }

  public boolean isDone() {
    return done;
  }

  public void setDone(boolean isDone) {
    done = isDone;
  }

  public int compareTo(Object obj) {
    Todo todo = (Todo) obj;
    return getTitle().compareTo(todo.getTitle());
  }

  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("Todo {\n");
    sb.append("Title: \"");
    sb.append(getTitle() + "\";\n");
    sb.append("Task:  \"");
    sb.append(getTask() + "\";\n");
    sb.append("}");
    return sb.toString();
  }
}

Then I have a class that stores and loads my todos:

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class ListStorage {
  Gson gson = new GsonBuilder().setPrettyPrinting().create();
  FileWriter writer;
  BufferedReader reader;

  public void storeList(List list, String filename) throws IOException {
    String json = gson.toJson(list);
    writer = new FileWriter(filename);
    writer.write(json);
    writer.close();
  }

  public List loadList(String filename) throws FileNotFoundException {
    reader = new BufferedReader(new FileReader(filename));
    List list = gson.fromJson(reader, List.class);
    return list;
  }
}

Then I have a 'Manager' class that is basically my controller:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Manager {
  private List<Todo> todos = new ArrayList<>();
  private ListStorage storage = new ListStorage();

  public List getTodos() {
    return todos;
  }

  public void setTodos(List newTodos) {
    todos = newTodos;
  }

  public ListStorage getStorage() {
    return storage;
  }

  public void add(String title, String task) {
    todos.add(new Todo(title, task));
    sort();
    try {
      storage.storeList(todos, "todos");
    } catch(Exception e) {
      e.printStackTrace();
    }   
  }

  public void remove(int index) {
    todos.remove(index);
    sort();
    try {
      storage.storeList(todos, "todos");
    } catch(Exception e) {
      e.printStackTrace();
    } 
  }

  private void sort() {
    Collections.sort(todos);
  }
}

And finally there is my main-class for testing my code (The bug seems to be here):

class CLITodo {
  public static void main(String[] args) {
    Manager man = new Manager();

    man.add("Hello", "Bye");
    man.add("Foo",   "Bar");
    try {
      man.setTodos(man.getStorage().loadList("todos"));
    } catch(Exception e) {

    }
    java.util.List<Todo> todos = man.getTodos();
    for (Todo t : todos) {
      System.out.println(t);
    }
  }
}

The error message I get when I leave the <Todo> in CLITodo class is:

Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to Todo at CLITodo.main(CLITodo.java:13)

When I remove <Todo> in CLITodo I get this error:

CLITodo.java:13:19: error: incompatible types
    for (Todo t : todos) {
                  ^
  required: Todo
  found:    Object

Why does this error occur? My Manager classes getTodos()-Method returns a List of type Todo yet the compiler tells me that it is just an Object (which it is of course but it is a collection as well, which should actually work). This is the first time this error occured and I really can't seem to find what is causing it.

2
  • 3
    I'm not sure this is your real code. man.getTodos() returns a List, but you're trying to assign it to a List<Todo>... Commented Dec 28, 2013 at 22:16
  • Changing the getTodos()-methods type into List<Todo> didn't work either if that was what you mean Commented Dec 28, 2013 at 22:21

1 Answer 1

5

When you don't specify what nested type to use to deserialize your JSON, like you do here

List list = gson.fromJson(reader, List.class); // All it knows is that the root json is a List

Gson uses LinkedTreeMap.

What you really want is

List list = gson.fromJson(reader, new TypeToken<List<Todo>>(){}.getType());
Sign up to request clarification or add additional context in comments.

2 Comments

This worked, and the list is being printed out correctly; thank you very much sir!
@selim You're welcome. As a side note, don't use raw types. They cause all sorts of headaches.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.