I'm trying to create a container that would accept specific classes only. Using generics as follows:
static class Test1<C extends Test1> {
C field = null;
public C getField() {
return field;
}
public void setField(C field) {
this.field = field;
}
}
static class Test2 extends Test1{
}
class MainTest {
public static void main(String[] args) throws Exception {
List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>();
Test1<Test2> newInstance = new Test1<Test2>();
list.add(newInstance);
Test1<Test2> value = list.get(1);
}
}
Just want to understand why this List> would accept a newInstance object, but compilation time error occurs while I'm fetching "Test1 value" back? Is there any chance to workaround the problem?
Thanks in advance.
UPDATE Many noticed that " Test1<? extends Test1>
, where ? MAY NOT be equal to Test2." I totally agree but as far as I understand in this case I need to type cast the extracted value to Test1<Test2>
and that means that the whole point of generics is lost in this case... Please correct me if I'm wrong.
Because when you list.get(1)
returns Test1<? extends Test1>
Test1<? extends Test1>
, where ?
MAY NOT be equal to Test2
.
On the onther hand list.add(...)
accepts Test1<? extends Test1>
Test1<? extends Test1>
, ie Test1 with ANY generics parameter which is inheritor of Test1.
This is because you can store a Test1<> with every object that is a child of Test1 as a typed parameter. Let's say you have class Test3 extends Test1 then you would have
Test1<Test2> value = list.get(1);
but how the list would be sure that the element with index 1 has a generic type Test2 but not Test3 as it accepts every subtype of Test1 ().
The proper way to fetch the element is using
Test1<? extends Test1> test1 = list.get(1);
You could solve the problem by writing
Test1<? extends Test1> value = list.get(1);
instead of
Test1<Test2> value = list.get(1);
or by making a cast to Test1.
List<Test1<? extends Test1>> list = new ArrayList<Test1<? extends Test1>>();
this is a read only list, you can only insert null to this list, nothing else
instead use below:
List<Test1<? extends Test1>> list = new ArrayList<Test1<XXX>>(); where XXX extends Test1
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.