Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you pass a List<objects that implement an interface> to a method?

I have a servlet with several methods that get a list of objects from the DAO, turn the list into JSON, and send it back in the response. Every list is made of objects that have a method:

public String getAsJson(){...}

And the servlet has a bunch of mostly identical methods that look like:

private String getUserListAsJson() {
    List<User> userList = this.dao.getUsers();
    StringBuilder builder = new StringBuilder();
    builder.append('[');
    // loops over the list appending the value of each objects getAsJson()
    builder.append(']');
    return builder.toString();
}

The problem is that I have about 6 methods (and growing) that look exactly like that except for different DAO queries. My idea was to create an interface that only had the definition for the getAsJson() method, make each bean implement that, and then have another method in the servlet that took objects that implemented that interface. Ended up looking like this:

public Interface JsonEnabled {
    public String getAsJson();
}

public class User implements JsonEnabled {
    ....
    @Override
    public String getAsJson() {...}
}

public class TheServlet {
    ...
    private String getUserListAsJson() {
        List<User> userList = this.dao.getUsers();
        return this.getListAsJson(userList);
    }
    private String getListAsJson(List<? implements JsonEnabled> list) {
        // The loop code that is in each method.
    }
}

That doesn't compile though. After looking up some documentation from Oracle, you can only have extends and not implements for generic parameters. Making all the classes extend from an Abstract Class that just has the getAsJson() method doesn't make sense semantically (the classes are unrelated).

I haven't found a good solution on SO or just googling around, so any help/insight would be appreciated.

like image 380
Windle Avatar asked Apr 10 '12 13:04

Windle


2 Answers

For generic wildcards the keyword extends works for both classes and interfaces:

private String getListAsJson(List<? extends JsonEnabled> list) { ... }

extends has slightly different meaning when used for defining generic bounds - it essentially translates to "is, or extends, or implements".

like image 154
Paul Bellora Avatar answered Nov 06 '22 01:11

Paul Bellora


Why don't just use

private String getListAsJson(List<JsonEnabled> list) { ... }

?

like image 45
Vadym S. Khondar Avatar answered Nov 06 '22 02:11

Vadym S. Khondar