This question already has answers here:
Difference between generic type and wildcard type
(8 answers)
Closed 8 years ago.
In the Java generics tutorial it says that <?> in a generic method means "unknown".
But I don't understand how <?> is different than <T>. Both mean that you can pass in any type-parameter you'd like. Please explain this operator.
The following excerpts come from http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
In generic code, the question mark (?), called the wildcard,
represents an unknown type. The wildcard can be used in a variety of
situations: as the type of a parameter, field, or local variable;
sometimes as a return type (though it is better programming practice
to be more specific). The wildcard is never used as a type argument
for a generic method invocation, a generic class instance creation, or
a supertype.
And another:
The unbounded wildcard type is specified using the wildcard character
(?), for example, List. This is called a list of unknown type.
There are two scenarios where an unbounded wildcard is a useful
approach:
If you are writing a method that can be implemented using functionality provided in the Object class.
When the code is using methods in the generic class that don't depend on the type parameter. For example, List.size or List.clear. In
fact, Class is so often used because most of the methods in
Class do not depend on T.
The second bullet makes the biggest distinction. Use '?' When you don't need to call operations on the actual type. See the link provided if you need more details. There are several sub sections under this wild cards section that cover different points so don't stop with just the page you are directed to.
Related
I have just came accross a question which I don't quite understand.
I have following variable (class field):
List<Validator<?, Data>> validators;
Now I want to assign some validators' instances to this list, then:
validators = Arrays.asList(validatorsFactory.create(Obj1.class));
Where the create method returns Validator<?, Data>
And there is a problem: I need to specify generic type of that list, due to wildcards. Okay, right version is:
validators = Arrays.<Validator<?, Data>>asList(validatorsFactory.create(Obj1.class));
But, when I add two elements instead of one I dont have to specify any generic type. How does Java know that the wildcards are the same?
validators = Arrays.asList(
validatorsFactory.create(Obj1.class), validatorsFactory.create(Obj2.class)
);
My understanding of that was that all wildcards are different placeholders when they are an arguments to a method.
Same applies to Guava's: ImmutableList.of
Thanks in advance
When you have an argument with a wildcard at the top level, e.g. Validator<?, Data>, you are allowed to pass it to a generic method with a type variable in the place where the wildcard is, e.g. public <T> void foo(Validator<T, Data>). This is called wildcard capture.
This case is a little different, because the Arrays.asList() takes parameters of type T. For some reason in your first case, it is keeping the capture when inferring the type of T, so it infers T to be Validator<capture #XXX, Data>, which is not the T that you want.
In your second case, I am guessing that the fact you have two arguments, both of type Validator<?, Data>, somehow makes it impossible for T to be inferred to contain a capture, since the two wildcards would have two different captures, so it just infers T to be Validator<?, Data>, which is what you wanted in the first place.
This question already has an answer here:
Type parameter vs unbounded wildcard
(1 answer)
Closed 7 years ago.
I have a method where I want to accept class types that must extend an abstract class. What is the difference between
<T extends AbstractClass> void myMethod(Class<T> clazz);
and
void myMethod(Class<? extends AbstractClass> clazz); ?
I wouldn't be able to directly reference the type inside the method in the second case. Is there any difference in which class types could be passed to these two methods?
No, there is no difference between the argument types compatible with the two method signatures you presented. Personally, I would use the parameterized version if I needed to reference the exact type represented by the argument, but otherwise I would use the wildcard version.
In the 1st one you will also be able to return T (or any type parameterized with T: List<T>, Set<T> and so on...) , without needing to cast it
<T extends AbstractClass> T myMethod(Class<T> clazz);
And use it as :
Subclass parameterInstance =...
Subclass i1 = myMethod(parameterInstance.getClass());
This question has been asked many places, notably here and here.
Both questions deal primarily with unbounded wildcards and generic types but the same principles apply here. I'd also recommend reading one of the links (Angelika Langer - Java Generics FAQs) provided by one of the answers to the other questions (placed here for convenient).
Whilst in your specific case there is no difference, the difference comes down simply to how you would be dealing with the type data internally (within the method). Go with what seems to describe your purpose the best. If you are dealing with data of unknown type and you require the specific input type to be specifically usable within the method, you'll need to go with the generics approach. If on the other hand, you do not and can suffice with treating all input data as simply of the bounding type (e.g. AbstractClass in your case) you may go with the bounded wildcard approach.
This question already has answers here:
Why does this Java method appear to have two return types?
(3 answers)
Closed 8 years ago.
In FindBugs source code, I found this method:
package edu.umd.cs.findbugs.ba;
....
public class ClassContext {
....
private <Analysis> Analysis getMethodAnalysisNoException(Class<Analysis> analysisClass, Method method) {
try {
return getMethodAnalysis(analysisClass, method);
} catch (CheckedAnalysisException e) {
IllegalStateException ise = new IllegalStateException("should not happen");
ise.initCause(e);
throw ise;
}
}
....
}
What is the meaning of first <Analysis> in the method declaration?
It is a Generic type. They were introduced in Java 1.5 and allow you to specify additional compile time information which is meant to reduce bugs. It is important to note type erasure when you talk about Java Generics, because it is a compile time feature that information is erased at runtime, and it is an Object (that happens to be of type Analysis).
Here is some info I wrote about generics in this post: What does generic type mean?
In Java, "Generics" are parameters for types. This may sound confusing but here is a simple explanation. If you were making a class that many other classes will inherit from, you want to make it broad and flexible. So you would use a "Generic" type to create instance variables.
Generic types can be implemented as: (Note the diamond brackets "<>")
public class TestClass<T>
Creating Instances With Generics This may a little more in depth than your question, but I thought I would mention how to create an instance of a generic class.
Note the argument that goes in the diamond braces has to be an object. For primitive types, you can just use Int, Double, Float (with capital first letters) and Java will "auto-box" the objects into primitive types.
ClassName<String> obj = new ClassName<>();
As per my knowledge its a Bytecode Analysis Framework. Definitely Analysis is a class.
You can find few code sample here.
What is the meaning of first <Analysis> in the method declaration?
This type is a generic type of declaration of method.
Hope it will help you.
The < Analysis > is a very poorly named type variable. That means the method getMethodAnalysisNoException can be called with a parameter of Class<T> for any type T and will return an instance of the type T if it doesn't throw an unchecked exception. Usually we don't use type variable names that look like regular class names because it is confusing, as evidenced by the wrong answers several folks have given here.
How can you determine what type of object a generic is using at runtime ?
Due to type erasure, you cannot determine the actual type parameter(s) of a generic object instance. The best you can do is set things up so you can pass a class object to code that needs to know the actual type. For example, this is what java.util.EnumMap does in one of its constructor.
If you mean the T in List<T> (for instance), you can't, because Java uses type erasure. At runtime, a List<T> just looks like a List. This is true except in the edge case of anonymous classes, where it's possible if you jump through hoops to find the parameter type. But in the general case, you cannot. You usually have to communicate that information separately.
First we explain What is Generic
Generic in Java is one of important feature added in Java 5,
From Oracle's documentation:
Generics were introduced to the Java language to provide tighter type
checks at compile time and to support generic programming. To
implement generics, the Java compiler applies type erasure to:
Replace all type parameters in generic types with their bounds or
Object if the type parameters are unbounded. The produced bytecode,
therefore, contains only ordinary classes, interfaces, and methods.
Insert type casts if necessary to preserve type safety.
Generate bridge methods to preserve polymorphism in extended generic types.
Type erasure ensures that no new classes are created for parameterized
types; consequently, generics incur no runtime overhead.
Now how to make possible to get the generic type on runtime, with the help of this link
read: http://www.west-wind.com/weblog/posts/2011/Nov/11/Dynamically-creating-a-Generic-Type-at-Runtime
It is not possible to get the object type of "Generics" at run time. If we use object.getclass(), so we can get object of any class with the class name.
What is java.lang.Class<?>[] in java . Specifically what is <?>.
I am a beginner in java , I cannot figure out what is the meaning of <?>
Thanks,
Puneet
A type argument for a parameterized type is not limited to a concrete
class or interface. Java allows the use of type wildcards to serve as
type arguments for parameterized types. Wildcards are type arguments
in the form "?", possibly with an upper or lower bound. Given that the
exact type represented by a wildcard is unknown, restrictions are
placed on the type of methods that may be called on object of the
parameterized type.
Source:
Generics In Java
Also:
Wildcards in Generics
Instances of the class Class represent classes and interfaces in a running Java application. The <?> part indicates that a Class can be a represantation of any java object, basicly. This is Java Generics.
<?> means any type.
Since all java classes directly/indirectly inherit Object, you can simply think of <?> as <Object>, although this is not so precise.