this morning I came across this code, and I have absolutely no idea what that means. Can anyone explain me what do these <T> represent? For example:
public class MyClass<T>
...
some bits of code then
private Something<T> so;
private OtherThing<T> to;
private Class<T> c;
Thank you
You have bumped into "generics". They are explained very nicely in this guide.
In short, they allow you to specify what type that a storage-class, such as a List or Set contains. If you write Set<String>, you have stated that this set must only contain Strings, and will get a compilation error if you try to put something else in there:
Set<String> stringSet = new HashSet<String>();
stringSet.add("hello"); //ok.
stringSet.add(3);
^^^^^^^^^^^ //does not compile
Furthermore, another useful example of what generics can do is that they allow you to more closely specify an abstract class:
public abstract class AbstClass<T extends Variable> {
In this way, the extending classes does not have to extend Variable, but they need to extend a class that extends Variable.
Accordingly, a method that handles an AbstClass can be defined like this:
public void doThing(AbstClass<?> abstExtension) {
where ? is a wildcard that means "all classes that extend AbstClass with some Variable".
What you see here is something called Generics. They were introduced to Java in release 1.5.
You can read about them here and here. Hope this helps.
Imagine you're writing a List or Array class. This class must be able to hold elements of an unknown type. How do you do that?
Generics answers this question. Those <T> you're seeing can be read as some type. With generics you can write class MyList<T> { ... }, which in this context means a list that holds some type.
As an usage example, declare a list to store integers, MyList<Integer> listOfInts, or strings, MyList<String> listOfStrings, or one class you've written yourself MyList<MyClass> listOfMyClass.
What you are seeing is Java generics, which allows classes and methods to be parameterized by other classes. This is especially useful when creating container classes, since it saves you having to create separate classes for "a list of integers", "a list of strings", etc. Instead, you can have a single "list of some type T, where T is a variable" and then you can instantiate the list for some specific type T. Note that Java generics is not quite the same as template types in C++; Java generics actually use the same class definition but add implicit casting (generated by the compiler) and add additional type-checking. However, the different instantiations actually make use of the same exact type (this is known as erasure), where the parameterized types are replaced with Object. You can read more about this at the link.
Since noone has mentioned it yet, there is a very comprehensive guide/FAQ/tutorial on generics which can be found on Angelika Langer's site.
Related
Say you have some class with type T:
class MyClass<T extends SomeOtherClass> {
....
}
Now, you want to store instances of this class into a collection, but you don't really care about the type. I would express this as following:
private final List<MyClass> entries = new ArrayList<>();
Is there any good reason/advantage to write the following instead?
private final List<MyClass<?>> entries = new ArrayList<>();
Or even:
private final List<MyClass<? extends SomeOtherClass> entries = new ArrayList<>();
I myself can only find a bad reason to do this: whenever the type definition of MyClass changes (for example addition of another type), you have to alter the List<MyClass<?>> or List<MyClass<? extends SomeOtherClass>> definitions all over your code as well.
update
To update my question:
Why isn't the compiler to be able to track the type(s) of MyClass when your write List<MyClass> (or even List<MyClass<? extends SomeOtherClass>>)? He knows that MyClass is defined as MyClass<T extends SomeOtherClass>, so why isn't he able/allowed to do that when you write List<MyClass>?
In other words, why is List<MyClass> not equal to List<MyClass<?>> (or even List<MyClass<? extends SomeOtherClass>>)? The compiler has all the information to make that conclusion himself, afaik.
The ? wildcard is useful when you don't need to refer to the type again and so you don't need to make a specific identifier.
Your first snippet starts with class MyClass<T extends SomeOtherClass>. This is necessary when T is important later on, perhaps to declare a field argument, or return type. For example:
class MyClass<T extends SomeOtherClass> {
private final List<T> aListOfT;
public T getSomething() {
return this.aListOfT.get(0);
}
Since MyClass is a generic type, all references to it should be qualified to avoid avoidable runtime errors. Thus when you declare List<MyClass> you get a compiler warning that you use the raw type MyClass. If you don't care at that location in the code what sort of type MyClass is qualified with, then you use the ? to tell the compiler that you don't care and let it track the type and check all operations for validity.
Your first declaration means, you are not giving any information about your generic data for the future reflection systems, could be used by plugins, which are written for your main program.
The second declaration tells them, that the field contains an Object generics.
The third one is the more specific, it means, that the reflection systems knows, what is this field about detailly.
Using the first type, java will assume that the generic type is Object. The reason for this is, that generics were introduced in version 1.5. Before then the collection-classes stored everything as an object. For compatibility reasons giving no generic parameter means that you are using object.
The second type simply says you don't know or don't care what type it is. This information is preserved when the code gets compiled. So other programmer who might use your code would know that you don't care.
Because of java's type-erasure, there is no difference between these two at runtime.
With the last form you say:
I don't care what it is, but it has to be SomeOtherClass or a derivated type. Which is the same as:
List<MyClass<SomeOtherClass>>
You can also do it the other way around:
List<MyClass<? super SomeOtherClass>>
says that you don't care what type it is, unless it is a supertype of SomeOtherClass.
I've just been diving into Java generics and have come across something puzzling. I have a List of Class objects. These Class objects are of classes that extend the class MyType. What I want to do is the following:
Class<? extends MyType>[] myArray = myList.toArray( Class<? extends MyType>[] );
Now I know this won't work. But how is it possible to create such an array? My trouble is that I need to pass this List as a Class array to a method. I'd rather avoid #SuppressWarnings and figure out if it's possible.
You can pass the list as such but not instantiate as such. Must be instanced with concrete class substitutiona but then be assigned to whatever the captures.
There is rule "don't mess arrays with generics". There is the restriction in Java that states that creation of arrays of parameterized types is not allowed. So, the answer for your question is no, you can't create an array of any generic types.
UPD: Consider using any collection type instead of arrays. They will work just fine.
Or you can (but better not do that though) use array of non-generic elements and then cast them to appropriate type, suppressing warnings.
You have to provide the concrete type here which you also should know because of the type of myList.
Im relatively new to Java, and I recently came across a syntax that I have never seen before.
public class loadSomeData extends AsyncTask<String, Integer, String>{ etc..}
The part that confuses me is the stuff between the <> brackets. I understand what each of the Types are used for in this class, but why declare them in the class declaration?
More specifically what is this: <DataType> called in Java so I can research it?
Thank you
You're looking for "generics" in Java.
In brief, a collection class (or any class, really) may declare a parameterized type using that syntax so that users of the class can ensure that only objects of the same type will be stored in its collections (or otherwise operated on by it).
Before generics there was no type safety on collections such as lists:
List numbers = new ArrayList();
numbers.add(Integer.valueOf(123)); // OK
numbers.add("foo"); // Uh-oh!
But now you can ensure that only the type(s) you declare can be added:
List<Number> numbers = new ArrayList<Number>();
numbers.add(Integer.valueOf(123)); // OK
numbers.add("foo"); // Compile-time error!
You are seeing Java's Generics feature. Here is a good tutorial: http://docs.oracle.com/javase/tutorial/java/generics/index.html
The <DataType> structure is referred to as the type paramaters of the AsyncTask class. AsyncTask is a genericized Java class. This means that it can use different generic classes in its operation. See the link above.
AsyncTask is a generic type, because it can be parameterized with types just as java.util.List, java.util.Set, and numerous standard Java classes.
Read the Java tutorial about generics to learn more.
It's useful to declare them in the class declaration because loadSomeData (which should be named LoadSomeData, or even better: SomeDataLoader) as a specialization of AsyncTask that handles String, Integer and String, and not any other types.
I'm working through some sample code and then this appeared:
public abstract class RandomPool<T> extends Pool {
//Class...
}
What's <> used for? And why is just T inside these? This seems to be very random for me. However, how can I use it in a longer perspective of making programs?
Thanks and tell me if I need to add more details!
See Java Generics
T stands for "Type"
Generics
T is a placeholder for whatever type is used at runtime. For example you could use:
RandomPool<String> pool;
T would refer to String in that case.
Read the Java Generics Tutorial
That thing is called a type parameter.
Basically, your class RandomPool is a generic class. It has a type parameter so that it could use different classes provided by caller. See Java collections like List it will be much more clear.
Also, note that T is not a keyword, you could name the type parameter any way you like. It's just a convention to use T like Type. Some collections use E like Element.
This is how you declare the type of a Generic that your class accepts. The example you presented reads:
abstract class ObjectPool of type T extends Pool
very short desc T is a compiler variable. with your code posted you can have a randomPool of Strings, eg: RandomPool<String> a randomPool of Foos, eg: RandomPoo<Foo>, .... Pretty much anything.
read dom farr's link with this in mind
It's the java way (Generics) to implement templates (in C++). T represents the type of the element you want to use for a particular object instantiated.
You can easily understand generics by looking at this example:
Hashmap <String, int> hm = new HashMap<String,int>();
hm.put("k1",1);
hm.put("k2",2);
Iterator it = hm.iterator();
while (it.hasNext()){
String curr = it.next();
int value = hm.get(curr);
}
Here, you can understand that Hashmap takes 2 types (general types, you can use whatever you want.. from Natives to custom classes etc etc).
RandomPool, in the example you posted, should be instantiated with a particular custom type! So, when you decide to use it, you should write code this way (i.e.):
RandomPool<String> myR = new RandomPool<String>();
There's nothing fancy about this. It's just Java's syntax for rank-1 parametric polymorphism.
I have a CacheListener<T> and a CacheListenerLoader which implements CacheListener<Activity>.
I then have a Provider<CacheListenerLoader> Guice so the type has to be CacheListenerLoader so google produces the right ones.
Line 4 does not compile:
CacheListenerLoader listTemp;
OurCacheListener<Activity> t2 = listTemp;
Provider<CacheListenerLoader> prov;
Provider<OurCacheListener<Activity>> temp = prov;
That is important because I am trying to call this method:
private <T> void put(Class<T> klass, Provider<OurCacheListener<T>> provider)
then pass the right combination of Provider and class type so that I'm guaranteed at compile time the class type lookup results in something that can process the given class.
I pass in Activity.class and temp to my put method and that works fine and checks the types. The key is the 4th line above is not working which looks like generics is failing me here but I am not sure why since it is a compile time thing.
I'm going to assume that CacheListener is the correct type and what you want to do is pass your Provider<CacheListenerLoader> to your put method.
The problem here is that a Provider<CacheListenerLoader> is not a subtype of Provider<CacheListener<Activity>> in the world of generics. It's just like how you can't assign a List<Integer> to the type List<Number>... because if you did that, you'd be allowed to add Doubles to the List<Number> and then try to retrieve them from the List<Integer> as Integers, causing a ClassCastException.
Of course, since you can't add anything to your providers, this isn't an issue. But you still have to tell the type system that! What you need to do is change the signature of put to:
private <T> void put(Class<T> clazz,
Provider<? extends CacheListener<T>> provider)
This says that you just want any provider that can return something that is a CacheListener<T> and that you don't need to be able to call any methods that try to consume a CacheListener<T>.
You need wo use some wildcards. Which ones exactly is not easy for me to tell because you provide so little code, but I'd say something like
Provider<? extends OurCacheListener<Activity>> temp = prov;
For reference, read
Java Generics and Collections
Angelika Langer's Generics FAQ
Java theory and practice: Going wild
with generics, Part 2
you stumbled over a generics restriction: Provider and Provider are not compatible, even if A extends or implements B.