I'm looking to understand all of the detailed reasons/motivations/uses for each of these, but there are so many combinations while it all seems the same to me, that I am confused about the nuances of what I think is called generics(wildcards, Object, T, E etc., don't know if all of that falls under generics)
If I have something like this I want to make an arraylist out of:
Media<T> //Baseclass
Book<T> //Subclass
Movie<T> //Subclass
Which of these would be most appropriate to make/use in this case, and why?(If necessary, let's assume I'll only use String and Integer for these Books, Movies) :
ArrayList<Media> = new ArrayList<Media>;
ArrayList<Media<T>> = new ArrayList<Media<T>>;
ArrayList<Media<?>> = new ArrayList<Media<?>>;
ArrayList<? extends Media> = new ArrayList<? extends Media>;
ArrayList<Object> = new ArrayList<Object>;
ArrayList<> = new ArrayList<>;
And if the baseclass was abstract, would that make a difference/impact the choice?
I know that Object is the super-super class and "can assume any form", I know wildcards signal that the next object may be any kind, but so do E and T, right? I know that ? extends Media means it will be a type of Media. It all seems the same to me otherwise, I wouldn't know how to justify a specific choice.
EDIT: Complete example below
import java.awt.*;
import java.util.ArrayList;
public class Something {
public class Media<T>{
T data;
public T getData(){ return this.data; }
public void setData(T data){ this.data = data; }
}
public class Book<T> extends Media<T>{
T data;
@Override
public T getData(){ return this.data; }
@Override
public void setData(T data){ this.data = data; }
}
public class Movie<T> extends Media<T>{
T data;
@Override
public T getData(){ return this.data; }
@Override
public void setData(T data){ this.data = data; }
}
ArrayList<Media> arrList;
public Something() {
this.arrList = new ArrayList<Media>();
this.arrList.add(new Book<Integer>());
this.arrList.add(new Movie<String>());
this.arrList.get(0).setData(12);
this.arrList.get(1).setData("Hello");
System.out.println(this.arrList.get(0).getData()+10);
System.out.println(this.arrList.get(1).getData()+10);
}
public static void main(String[] args) {
Something s = new Something();
}
}
This is not a complete answer, but see this question on the effects of using "super" or "extends" in generic type specifications. The short version is that Collection<? extends T>
Collection<? extends T>
is read-only while Collection<? super T>
Collection<? super T>
is append-only.
For this reason I personally prefer to completely avoid both these qualifiers since they are generally more restrictive than a simple Collection<T>
.
However, they are sometimes useful when designing APIs for purposes of contra and counter variance (see this question )
Collection<?>
I only use when dealing with legacy code (that doesnt use generics) to avoid a compiler warning. Its effectively the same as Collection<Object>
, but to me is clearer. I try never to write new code that requires <?>
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.