[ACCEPTED]-How to generically specify a Serializable List-serialization

Accepted answer
Score: 10

You need to declare your variable type as 7 Result<? extends List<Integer>>.

The type checking knows that List isn't serializable, but 6 a subtype of List can be serializable.

Here is some sample 5 code. The interface implementation was just 4 done with anonymous inner classes. You can 3 see that the getResult will return a List<Integer> on the 2nd 2 object

   Result<Integer> res = new Result<Integer>() {

        Integer myInteger;

        private static final long serialVersionUID = 1L;

        @Override
        public Integer getResult() {
            return myInteger;
        }

        @Override
        public void addResult(Integer input) {
            this.myInteger = input;
        }
    };

    Integer check = res.getResult();


    Result<? extends List<Integer>> res2 = new Result<ArrayList<Integer>>() {

        ArrayList<Integer> myList;

        private static final long serialVersionUID = 1L;

        @Override
        public ArrayList<Integer> getResult() {
            return myList;
        }

        @Override 
        public void addResult(ArrayList<Integer> input) {
            this.myList = input;
        }

    };

    List<Integer> check2 = res2.getResult();

Edit: Made the example more complete 1 by implementing a void addResult(T input) interface method

Score: 3

Although the List interface doesn't implement 5 Serializable, all of the built-in Collection 4 implementations do. This is discussed in 3 the Collections Implementations tutorial.

The Collections Design 2 FAQ has a question "Why doesn't Collection extend Cloneable and Serializable?" which talks about why 1 Sun designed it without extending Serializable.

Score: 2

You could simply declare the variable as 6 Result<ArrayList<Integer>>. As long as you still program to the List interface, you 5 haven't really sacrificed replaceability.

I 4 was going to also suggest creating a new 3 interface ListResult:

public interface ListResult<T extends Serializable & List<E extends Serializable>>
        implements Result<T> {
    T getResult();
}

but then you would still have 2 to declare the variable as ListResult<ArrayList<Integer>>. So I'd go the 1 simpler route.

Score: 0

If your intention is to use the Result type 10 for lists in general, and what you want 9 is to make sure the elements of the list 8 are serializable, you could define it like 7 this:

public interface Result<T extends List<? extends Serializable>> {}

That way, you could define something 6 like:

Result<List<Integer>> r;

But something like this would not compile:

Result<List<List>> r;

Now 5 if you want to use the result both for, say, Integer, and 4 for List, then the type is not required 3 to be serializable, right? In that case 2 I don't really understand what your goal 1 is.

Score: 0

You kind of can, I think:

public class Thing<T extends Serializable> implements Serializable {
    private static class Holder<V extends Serializable> {
        private final V value;
        private Holder(V value) {
            this.value = value;
        }
    }
    private Holder<? extends List<T>> holder;
    private <V extends List<T> & Serializable> void set(V value) {
        holder = new Holder<V>(value);
    }
}

Does that look 8 ugly enought for you?

Can I suggest that 7 you do not attempt to enforce implementing 6 Serializable using the Java static type system? It's 5 only an interface because annotations weren't 4 about back then. It's just not practical 3 to enforce it. OTOH, you could enforce it 2 using a type checker that does static analysis 1 in a closed system.

Score: 0

The way I ended up solving this problem 5 is to use this as the interface:

public interface Result<T> extends Serializable{
    T getResult();
}

Then create 4 an implementation for each of the different 3 types of collections as well as one for 2 any object.

So, for example here is what 1 the ListResult class would look like:

public class ListResult<T> implements Result<List<T>>{
    public List<T> getResult(){
        //return result
    }

    public <V extends List<T> & Serializable> void setResult(V result){
        //store result
    }
}

More Related questions