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.
Related
It says in the documentation, that
...wildcard, represents an unknown type. The wildcard can be used ... as the type of a ... local variable
From my point of view, this means I can write something like
int a;
? b;
but I can't.
Is it really possible?
That's an appallingly worded statement, and I'm surprised to see it in the documentation. You can't use a wildcard as the type of a variable, but you can use a wildcard in the type of a variable.
? a; // no
List<?> b; // yes
Nope, not possible. Java is strongly typed, the ? is used in a variety of cases (mostly to do with generics) when you can't know the type ahead of time.
I would suggest you read the rest of the documentation you posted, it has some excellent examples as to how to use ?.
This is the documentation for generics. Java is strongly typed, and will not accept a wildcard as a variable type.
Wildcards will only be accepted in generic types like these:
List<?> x = new ArrayList<>()
or
List<? extends String> x = new ArrayList<>()
You're confusing what purpose the unbounded wildcard has. In general, it implies that you either do not know or do not care about the type when dealing with various things, such as collections.
For example, a List<?> simpleList is a list that contains an unknown type.
In general, ? extends Object, so if you ever really think you need ?, you'd want to use Object instead.
No it is not possible, the Java Tutorial reefers that you can define a local variable using a wildcard like this:
List <?> localVariable;
but not like this:
? localVariable;
A wildcard is used exclusivity in Java only in Generic brackets, replacing a Type Parameter.
There are methods like these which require Class literals as argument.
Collection<EmpInfo> emps =
SomeSqlUtil.select(
EmpInfo.class,
"select * from emps");
or
GWT.create(Razmataz.class);
The problem presents itself when I need to supply generic specific classes like
EmpInfo<String>
Razmataz<Integer>
The following would be wrong syntax
Collection<EmpInfo<String>> emps =
SomeSqlUtil.select(
EmpInfo<String>.class,
"select * from emps");
or
GWT.create(Razmataz<Integer>.class);
Because you cannot do syntax like
Razmataz<Integer>.class
So, how would I be able to squeeze a class literal out of
EmpInfo<String>
Razmataz<Integer>
so that I could feed them as arguments to methods requiring Class literals?
Further info
Okay, I confess that I am asking this primarily for GWT.
I have a pair of GWT RPC interface Razmataz. (FYI, GWT RPC interface has to be defined in server-client pairs). I plan to use the same interface pair for communicating whether it be String, Integer, Boolean, etc.
GWT.create(Razmataz) for Razmataz<T>
complains that, since I did not specify T, GWT compiler treated it as Object. Then GWT compiler would not accept Object class. It needs to be more specific than being an Object.
So, it seems there is no way for me to tell GWT.create what T is because a Class literal is a runtime concept while generics is a compile time concept, Right?
Quote from Java Generics and Collections, section 7.2:
Class literals are also restricted; it is not even syntactically valid to supply a type parameter to the type in a class literal. Thus, the following fragment is illegal:
class ClassLiteral {
public Class<?> k = List<Integer>.class; // syntax error
}
Indeed, Java's grammar makes a phrase such as the preceding one difficult to parse, and it may trigger a cascade of syntax errors [...]
This syntax problem leads to an irregularity. Everywhere else that a reifiable type is required, you may supply either a raw type (such as List) or a parameterized type with unbounded wildcards (such as List<?>). However, for class tokens, you must supply a raw type; not even unbounded wildcards may appear. Replacing List<Integer> with List<?> in the preceding code leads to a similar error cascade.
So, you have no choice but use only raw types in class tokens, like
GWT.create(Razmataz.class);
You can't.
Use an unsafe cast:
Collection<EmpInfo<String>> emps =
(Collection<EmpInfo<String>>) someMethod(EmpInfo.class);
Someone left a short but concise answer here, which I was about to choose as the answer. Unfortunately, that person deleted that answer. If that person would be so kind to re-post that answer for me to select. In the mean time, let me state that answer and how I made use of it.
This is what I should have thought of,
Interface RazmatazString extends Razmataz<String>{}
GWT.create(RazmatazString.class);
Basing on the answer that was deleted,
I would have a basic Razmataz interface pair the does a lot of stuffs, which I am too lazy to repeat.
Abstract class Razmatazer{
.....
Interface Razmataz<T>{
// does a lot of RPC stuffs
}
Interface RazmatazAsync<T>{
// does a lot of RPC stuffs
}
RazmatazAsync<?> razmatazAsyncRPC;
}
The concept is not to instantiate razmatazAsyncRPC handle at the base class but at the derived class.
For T = String
StringRazmatazer extends Razmatazer{
Interface RazmatazStringAsync extends RazmatazAsync<String>{}
Interface RazmatazString extends Razmataz<String>{}
razmatazAsyncRPC = GWT.create(RazmatazString.class);
}
Otherwise I would have to repeat ~100 lines of code, ~50 each for Razmataz and RazmatazAsync, over various T parametric values of String, Map, Boolean, Integer, etc.
The basic premise for overcoming this hurdle was - I am lazy to repeat those lines.
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.
Is it possible to use generics for arrays?
Arrays are already basic objects types, that is to say they're not a class that describes a collection of other objects like ArrayList or HashMap.
You cannot have an array of generified types either. The following is illegal in Java:
List<String>[] lists = new List<String>[ 10 ];
This is because arrays must be typed properly by the compiler, and since Java's generics are subject to type erasure you cannot satisfy the compiler this way.
I don't think this is possible because an array is a basic datatype.
But you can use a ArrayList to have something similar. In most of the cases using a collection of some kind pays of very well.
No. Arrays must have a compile-time type.
Have a look at this site. It should contain all generics related FAQs.
On a sidenote:
class IntArrayList extends ArrayList<Integer> { }
IntArrayList[] iarray = new IntArrayList[5];
If you subclass a generic object with a concrete type, that new class can be used
as array type.
Can you use it? Ofc.
Example:
public static <T> T[] mergeArrays(T[]... arrays) {
ArrayList<T> arrayList = new ArrayList<T>();
for (T[] array : arrays) {
arrayList.addAll(Arrays.asList(array)); //we steal the reflection from core libs
}
return arrayList.toArray(arrays[0]);//we steal the reflection from core libs
}
Is it a good idea? No. This code is just me playing around with generics. It led to a dark ally. You are better of using collections. They do what you want, and the syntax is prettier in the long run.
It's possible, but far from pretty. In general, you're better of using the Collections framework instead.
See Sun's Generics tutorial, page 15, for a detailed explanation.
If I ever want to, say, refactor the elements of an array to a better type, like from String to MyPairClass<String, Integer>, I tend to avoid the unchecked cast problem by making an empty subclass that "bakes in" the generic parameters, e.g.
class Maguffin {
private static class StringIntegerPair extends MyPairClass<String, Integer> {
private static final long serialVersionUID = 1L;
};
...
private final StringIntegerPair[] horribleOldArray;
...
This nested class will probably also need constructors that delegate up to the generic type's constructors, depending on what you do when adding new array elements. When passing the elements out of the enclosing class, just cast them up to the generic type:
...
MyPairClass<String, Integer> getSomethingFromTheArray(int index) {
return horribleOldArray[index];
}
...
}
All this being said, there should rarely be a need to do something like this if you are writing something new from scratch. The only real benefit of arrays over the Collections framework classes is that you can write them out as literals, and this will no longer be an advantage come next year when Java 8 is released.
Excerpt from Java Generics and collections.
Arrays reify their component types, meaning that they carry run-time information about the type of their components. This reified type information is used in instance tests and casts, and also used to check whether assignments into array components are permitted.
Therefore one is not allowed to have the suntax
new List<Integer>[10] ;
However the following is allowed
List<String>[] stringListArray=(List<String>[])new List[10];
Now this is not a really good practice. Such casts are not safe and should be avoided.
Which in general points to the fact that we should avoid using arrays of generic type.
If you mean having an array of List then the answer is no. new List<Number>[10] is illegal in java. questions like these could be answerable by searching it in Google alone or checking out the official Generics tutorial
For example, I could write either of these:
class example <T>
{
...
public void insert (T data)
{
...
}
}
or
class example
{
...
public void insert (Object o)
{
...
}
}
Is there a signficant difference between the 2 in terms of performance? With generics I could restrict the type of the parameter and with the second approach I guess it wouldn't be necessary to define the type of the object as it is created.
Also, with the second approach I could basically insert anything into the class, right? Whereas with generics every element in the class would be of the same type.
Anything else I'm missing?
The only reason to write the latter is if you must target an earlier JVM. Generics are implemented by type-erasure, so they have no runtime impact - only added compile time checking which will improve your code.
Of course if you need a collection which holds any old object, or a mix of several which don't have a common superclass, you need the plain Object variation (but then your class can still be generic and instantiated with new ...<Object>).
I think you pretty much nailed it. There is no performance difference. Generics are rationalized away (Type Erasure) when the code is compiled, and don't exist anymore at runtime. They just add casts when needed and do type-checking as you stated. Neal Gafter wrote a nice overview of how they work, of the current problems with Generics and how they could be solved in the next version of Java: http://gafter.blogspot.com/2006/11/reified-generics-for-java.html
There shouldn't be a performance difference.
However, Java does not offer parameter variance, so there are situations where you will be overriding pre-generics functions such as equals, compareTo, etc. where you will have to use Objects.
Some of the encounters where I had to use 'Object' instead of Generics were those of compulsion than of a choice. When working with pre-generic code or libraries built around pre-generic api, one has little choice. Dynamic proxies for example, Proxy.newProxy() returns Object type. Passing generic context (where a context can be anything) is another instance. Some of my friends argue that are as good as no-generics. As far as performance is concerned, there shouldn't be any overhead, considering type erasure.
Regarding performance, i agree with the people above.
Regarding this point of yours
"Also, with the second approach I could basically insert anything into the class, right? Whereas with generics every element in the class would be of the same type."
One more advantage of generics is there is a type check for assignment of the example instance itself.
Say for example you had an Example e1 of and another Example e2 of , type safety would be maintained and you would never be able to do e1=e2;
while with the object example, that would be possible.