Ok, so here is my problem:
I have a list containing interfaces - List<Interface> a
- and a list of interfaces that extend that interface: List<SubInterface> b
. I want to set a = b
. I do not wish to use addAll()
or anything that will cost more memory as what I am doing is already very cost-intensive. I literally need to be able to say a = b
. I have tried List<? extends Interface> a
, but then I cannot add Interfaces to the list a
, only the SubInterfaces. Any suggestions?
I want to be able to do something like this:
List<SubRecord> records = new ArrayList<SubRecord>();
//add things to records
recordKeeper.myList = records;
The class RecordKeeper is the one that contains the list of Interfaces (NOT subInterfaces)
public class RecordKeeper{
public List<Record> myList;
}
There's no way to do it that is type safe.
A
List<SubInterface>
cannot have arbitraryInterface
s added to it. It is a list ofSubInterface
s after all.If you are convinced that this is safe to do even though it is not type safe you can do
Just to explain why Java does not permit this:
List<Record>
is a list in which you can put any object implementingRecord
, and every object you get out will implementRecord
.List<SubRecord>
is a list in which you can put any object implementingSubRecord
, and every object you get out will implementSubRecord
.If it would be allowed to simply use a
List<SubRecord>
as aList<Record>
, then the following would be allowed:You see, this would not be typesafe. A List (or any opject of a parametrized class, in fact) can not typesafely change its parameter type.
In your case, I see these solutions:
List<Record>
from start. (You can addSubRecord
objects to this without problems.)List<? super Subrecord>
for the method which adds stuff.List<Record>
is a subtype of this.copy the list:
To exand a bit on th variation:
So, the rather simple solution a friend of mine found was this:
This works as I understand it because it takes baby steps.
List<SubRecord>
is aList<? extends Record>
, andList<? extends Record>
is aList<Record>
. It might not be pretty, but it works nonetheless.This works :
I mean it compiles, but you will have to cast your
List<? extends Record>
before adding anything inside. Java will allow casting if the type you want to cast to is a subclass ofRecord
, but it can't guess which type it will be, you have to specify it.A
List<Record>
can only containRecords
(includingsubRecords
), AList<SubRecord>
can only containSubRecords
.But A
List<SubRecord
> is not aList<Record>
has it cannot containsRecords
, and subclasses should always do what super classes can do. This is important as inheritance is specilisation, ifList<SubRecords>
would be a subclass ofList<Record>
, it should be able to contain ` but it'S not.A
List<Record>
and aList<SubRecord>
both areList<? extends Record>
. But in aList<? extends Record>
you can't add anything as java can't know which exact type theList
is a container of. Imagine you could, then you could have the following statements :As we just saw, this is only possible for
List<Record>
not for anyList<Something that extends Record>
such asList<SubRecord>
.Regards, Stéphane
THIS WORK, BUT YOU SHOULD BE WARN !!!!
You can cast from List of Objects to List of Interface in this way. But, if you get this list somewhere in your code and if you try to add something to this list, what would you add? Inteface or Subclass of this interface ? You actually loose information of the type of list, because you let it hold Interface, so you can add anything that implement this interface, but the list is holding the subclasses only, and you could easily get class cast exception if you try to do operations like add or get on this list with some other subclass. The solution is: Change The type of source list to
list<Interface>
instead of cast, then you are free to go :)You can't do that and be safe because
List<Interface>
andList<SubInterface>
are different types in Java. Even though you can add types of SubInterface to a list of Interface, you can't equate the two lists with different interfaces even if they're sub/super interfaces of eachother.Why is it that you want to do b = a so bad? Do you just want to store a reference to the SubInterface list?
On a side note, I suggest you read this documentation on the oracle site: http://download.oracle.com/javase/tutorial/java/generics/index.html It explains and goes deep into generics very well.