What is the meaning of the token <?> In Java?
What is the meaning of the <?> Token in this code copied from www.JavaPractices.com? When I replace it with the more traditional <T> view used for generic types, it does not compile. (Error: T may not be allowed for type.) Why?
// <?> occurs 3 times in the entire program. When it is replaced with <T> the // program no longer compiles. void activateAlarmThenStop() { Runnable myPeriodicTask = new PeriodicTask(); ScheduledFuture<?> soundAlarmFuture = this.executorService.scheduleWithFixedDelay(myPeriodicTask, startT, period, TimeUnit.SECONDS ); Runnable stopAlarm = new StopAlarmTask(soundAlarmFuture); this.executorService.schedule(stopAlarm, stopT, TimeUnit.SECONDS); } private final class StopAlarmTask implements Runnable { StopAlarmTask(ScheduledFuture<?> aSchedFuture) { fSchedFuture = aSchedFuture; } public void run() { CConsole.pw.println("Stopping alarm."); fSchedFuture.cancel(doNotInterruptIfRunningFlag); executorService.shutdown(); } private ScheduledFuture<?> fSchedFuture; } Edit: Of course, when we use type markers of a generic type, such as <T> , it should appear in the class declaration. There is no <T> and <?> In the class declaration here, but it still compiles and starts correctly.
It does not compile because your class is not generic (and not one of your methods). In this particular example, the joker (?) Means that ScheduledFuture can be parameterized with anything.
Sometimes it makes no sense to make a generic class generic if you use another generic class inside and you don't know the exact type to be used. In this example, you had three options:
- make StopAlarmTask shared (in this case it makes no sense)
- use a specific type in ScheduledFuture, but then it will be only one possible type of result, for example String or Integer
- use a wildcard character (
< ? >) - it allows you to retrieve anything as a result of FutureResult (String, Integer, your own class). You can also narrow down the scope of a possible generic type in some subclasses, such asScheduledGeneric< ? extends MyObject >ScheduledGeneric< ? extends MyObject >or in superclasses:ScheduledGeneric< ? super MyObject >ScheduledGeneric< ? super MyObject >
This is an example of using a template in a type argument. that is, a generic type. The parameterized wildcard type is an instance of a typical type, where at least one type argument is a wildcard. Examples of wildcard parameterized types: Collection<?> , List<? extends Number> List<? extends Number> , Comparator<? super String> Comparator<? super String> and Pair<String,?> .
A wildcard parameter with a parameter indicates a family of types containing specific instances of the generic type. The type of template used determines which specific parameterized types belong to the family.
This is a Generic Type ... Usually we set String, Object or any other objects as generic types ... but here they make it generic. and a generic type means the value that it can store or hold . it is commonly used in Collections ..
well there is no big difference between them .. - accepts all kinds of objects
<T>-is also called `formal type parameter` makes use of what ever type of object you pass in .. for instance you can do this with <T> and not with <?> public class Box<T> { private T t; // T stands for "Type" public void add(T t) { this.t = t; } public T get() { return t; } } for more details see http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf and http://download.oracle.com/javase/tutorial/java/generics/gentypes.html
A letter in brackets of type <T> will be a type parameter. You would say that the class StopAlarmTask<T> means that you parameterize the type StopAlarmTask with type T A type parameter T will become part of the type, sort of like a constructor argument becomes part of a new instance.
Then, when you declare StopAlarmTask , you must specify the type, for example. String to populate a parameter of type T Then you can refer to this type parameter inside the class body. For example, you can define methods that accept T or return T , or parameterize member variables such as fSchedFuture with T For example, if you parameterized the declaration StopAlarmTask<T> as StopAlarmTask<String> , then String would be written as T and wherever you used T within this StopAlarmTask , it would act as String .
However, in the code you specified, StopAlarmTask does not have a type parameter and cannot be parameterized by any type. Inside the body of the class there is no fixed type, which can be called T
On the other hand, <?> Means "I don’t know what type it will be, I don’t even know that it will be the type that someone used to parameterize StopAlarmTask ."
You could parameterize StopAlarmTask<T> , in which case you could have two variables:
private ScheduledFuture<T> fSchedFuture1; private ScheduledFuture<?> fSchedFuture2; The first declaration states that the parameter of type ScheduledFuture same as the parameter of type attached StopAlarmTask . For example. StopAlarmTask<String> will make fSchedFuture1 in ScheduledFuture<String> . The second declaration says that we do not know what a parameter of type ScheduledFuture , even if we know a parameter of type attached StopAlarmTask .
Assuming this.executorService is a subtype of ScheduledExecutorService (available since Java 1.5), the return type of scheduleWithFixedDelay() is equal to ScheduledFuture<?> . You cannot change the return type from ScheduledFuture<?> To ScheduledFuture<T> , ScheduledFuture<Integer> or anything else in this case. However, you can only change it to ScheduledFuture , since <?> Is a generic wildcard type pattern that approaches a raw type for backward compatibility.
See What is a raw type and why shouldn't we use it? for a good discussion of raw types and generics.
It can take any parameters, such as Object, String, Integer .... etc.
Now that you plan to use generics, you must specify the type inside the angel bracket.
EDIT:
<?> strictly applicable to collections. <T> used as a type or template for your regular class
joker ? may contain any type. If you want to use the same type for all methods / members, you can make a general class common. By writing StopAlarmTask<T> , you define the type T in the entire class.
private final class StopAlarmTask<T> implements Runnable { StopAlarmTask(ScheduledFuture<T> aSchedFuture) { fSchedFuture = aSchedFuture; } public void run() { /* */ } private ScheduledFuture<T> fSchedFuture; } StopAlarmTask not a generic type.
In the following example, you do not think Foo is a generic type.
class Foo { Foo(int i) { } doStuff(List<Integer> numbers) { } } The fact that the StopAlarmTask constructor uses a generic parameter does not make the generic class more than doStuff() makes Foo generic.
Use <?> To denote a "declaration" of a general type in a general way , that is, without specificity. In StopAlarmTask this is just a constructor parameter. This is a “use” of a generic type, not a generic type declaration, because it is “just” a parameter declaration.
In other words, the short answer is that the parameter in the method
StopAlarmTask(ScheduledFuture<?> aSchedFuture) { ... } applicable to all objects that are instances of ScheduledFuture<T> for all T.
See below for more information on generics.
Use <T> or <E> or whatever to declare a generic ScheduledFuture<T> . In particular, <?> Will not be used in the ScheduledFuture<> declaration, because the convention must use a single capital letter.
Please note that the following test code, if passed to the compiler, will show that the first class compiles and the second does not, so we can say that there is an agreement to use the letter, in fact, it would be an understatement.
class TGeneric1<E> { List<E> list = new ArrayList<E>(); TGeneric1(E value) { this.list.add(value); } E getHead() { return this.list.get(0); } } class TGeneric2<?> { List<?> list = new ArrayList<?>(); TGeneric2(? value) { this.list.add(value); } ? getHead() { return this.list.get(0); } } Illustrated in the following test code, there is no single restriction on the letter, so the following is also true.
class TGeneric1<EE> { List<EE> list = new ArrayList<EE>(); TGeneric1(EE value) { this.list.add(value); } EE getHead() { return this.list.get(0); } }