Understanding Class<?> - java

I came across this code:
public class RestfulAdage extends Application {
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> set = new HashSet<Class<?>>();
set.add(Adages.class);
return set;
}
}
I do not understand what Class<?> means.

Class<?> refers to a class of unknown type. The notation uses an unbounded generic which places no restriction on the type of class that can be added to the Collection. For example the following would not work
Set<Class<String>> set = new HashSet<Class<String>>();
set.add(Adages.class); // type not allowed

Class is a parametrizable class, hence you can use the syntax Class where T is a type. By writing Class, you're declaring a Class object which can be of any type (? is a wildcard). The Class type is a type that contains metainformation about a class.
It's always good practice to refer to a generic type by specifying his specific type, by using Class you're respecting this practice (you're aware of Class to be parametrizable) but you're not restricting your parameter to have a specific type.
Reference about Generics and Wildcards: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
Reference about Class object and reflection the (feature of Java language used to introspect itself): http://java.sun.com/developer/technicalArticles/ALT/Reflection/

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.
The following sections discuss wildcards in more detail, including upper bounded wildcards, lower bounded wildcards, and wildcard capture.
for more information click here

It refers to gererics. I suggest you read a little on it. Basically, you know only at runtime what type of object you get to work with. For example, Class can be Integer, String or even YourDefinedClassType
read here http://java.sun.com/developer/technicalArticles/J2SE/generics/

From : Wildcards
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.
Check the link, you will find more exhaustive documentation, examples etc.

Assume that you have a set of classes that belong to different types, and you have instances of different classes as well. So if you want to check whether these instances are instanceof one of these classes, you could iterate through these set and do the job. And for that kind of job, you better use a totally unrestricted set:
public boolean checkClasses(Set<Class<?>> typeLessClassSet, Set instances){
while(typeLessClassSet.hasNext()){
Class c = typeLessClassSet.next();
while(instances.hasNext()){
Object o = instances.next();
if(o instanceof c)
return true;
}
}
return false;
}

Related

What is the benefit of using Class<?> instead of Class as a method parameter type?

NB: This is not a duplicate of the question I have already linked to below. I obviously read that question/answer first before posting and did not have my question answered in any form.
This linked question does go into more detail explaining why the generic Class exists. However I don't get an answer specifically to the benefits of Class in my situation.
What does the generic nature of the class Class<T> mean? What is T?
I've written a utility method that accepts a parameter 'cl' of type Class and performs logic by using cl.isInstance(objectInstance) method.
However I've seen example code that declares parameters using the generic wildcard Class<?>.
Why not just use Class without the generic wildcard? Can't Class represent all possible class types including generics? What is the benefit, if any of using Class<?> in my situation?
The accepted answer in an existing related question (see below) does not actually provide a useful answer.
What does Class<?> mean in Java?
The main difference lies in the (self-)documentation of the code to the reader. A variable declared as Class<?> says: “the actual type represented by this Class instance is unknown or not representable at compile-time and I know that”. In contrast the type Class says: “I’m not using Generics here”, perhaps, because you don’t know that Class is generic, or you are a bit sloppy, didn’t understand the difference between Class<?> and Class, or this is very old pre-Generics code.
This has consequences for the code. E.g.
Class<?> unknownType=Object.class;
Class<String> string=unknownType;
produces a compile-time error as you are assigning an explicitly unknown type to a variable declaring a known type.
In contrast
Class nonGenericType=Object.class;
Class<String> string=nonGenericType;
will only produce a (suppressible) warning as you are performing a non-generic, aka unchecked, operation.
Regarding what you can do with a Class object, besides assignments, there is no difference, as, when you use it to create a new instance, the compile-time type of the returned reference will be the most abstract type there is, java.lang.Object, in both cases. Had Class methods receiving arguments related to the type parameter, a difference showed up as you can’t invoke such methods for an unknown type, Class<?> (it would be the same as trying to insert an element into a List<?>) while you could invoke such a method unchecked on a raw Class instance. But since there are no such methods, there’s no difference in functionality between Class<?> and Class.
Still, you should always use Class<?> to be sure that no accidental unchecked operations, like the assignment shown above, happen. If using Class doesn’t produce compiler warnings, you should check how to (re-)enable them. If the compiler silently ignores raw types or unchecked operations, there might be other problems, with other types than Class, hiding somewhere.
The difference between the wildcard type <?> and the raw type in this particular scenario is only whether the compiler will warn you or not. Otherwise they're equivalent, so if for some reason you don't wouldn't want to use the <?> syntax and you didn't care about compiler warnings, you could use the raw type without any problems.
Netbeans not complaining about the raw type is not correct behaviour, and my Eclipse will complain when using a raw Class.
The Class object has distinct usage patterns, which affect whether the type will be a concrete type (seen in method parameters as Class<T> clazz) or the wildcard Class<?>.
The most common form seen in the API is the concrete type, since it allows you to use newInstance() (primarily) in a type-safe way (making all Class<T> objects automatically type-safe factories), such as the following:
public static void List<T> fill(Class<T> clazz, int size) {
List<T> l = new ArrayList<T>();
for(int i = 0;i < size; i++)
l.add(clazz.newInstance());
return l;
}
So Class<T> is useful, but what about Class<?>? Well, not so much. As indicated at the beginning, it's just required for syntax compliance. The alternative would be to use a concrete T type redundantly.
public void foo(Class<?> clazz) {
// Do something non-typed, we don't have a type
}
vs.
public <T> void foo(Class<T> clazz) {
// Do something non-typed, even though we have a type T
}

What is that <E> in the method signature?

I was reading about Set interface from here which the code sipped below which is a generic method that removes duplicates from a collection.
My question is what is that **< E>** placed after static before Set<E> ?
I mean wouldn't that Set<E> be enough ? why <E> was there twice?
public static <E> Set<E> removeDups(Collection<E> c) {
return new LinkedHashSet<E>(c);
}
Here **<E>** is a generic type. Generic type is defined as
A generic type is a generic class or interface that is parameterized
over types. The following Box class will be modified to demonstrate
the concept. LINK
And regarding you question related to <E>. A good description for it can be found on the same tutorial
Type Parameter Naming Conventions
By convention, type parameter names are single, uppercase letters.
This stands in sharp contrast to the variable naming conventions that
you already know about, and with good reason: Without this convention,
it would be difficult to tell the difference between a type variable
and an ordinary class or interface name.
The most commonly used type parameter names are:
E - Element (used extensively by the Java Collections Framework)
K - Key
N - Number
T - Type
V - Value
S,U,V etc. - 2nd, 3rd, 4th types
You'll see these names used throughout the Java SE API and the rest of
this lesson.
This means that this method declares a generic parameter type which the class does not define; in this case, you MUST declare the parameter type before the return type (even if this "return type" is void).
Think about it this way. Remove the initial <E>. Your declaration would then become:
public static Set<E> removeDups(Collection<E> c)
What is E here? Unless it is a generic parameter type defined by the class itself, it can only be an existing class.
Hence this syntax. It allows you to define a generic parameter for use in the method signature.
It's just the generic type used within the method. Static methods that use generic types must specify that type before the return type.

ParameterizedType.getRawType() returns j.l.r.Type, not Class<?>?

ParameterizedType parameterized =
(ParameterizedType) List.class.getMethod("iterator").getGenericReturnType();
Type raw = parameterized.getRawType();
ParameterizedType#getRawType() returns a Type, not a Class<?> (although I get that java.lang.Class now implements Type). Is there a good reason why getRawType() doesn't declare its return type to be Class<?>? Are there extreme cases where getRawType()'s result might not be a Class<?>?
It's enough of a thrashing to work with j.l.r.Type as it is; this seems like an instance in which they could have saved us one downcast.
It must return a Class object, there's no other way.
Why? Who knows, maybe some idealistic bias. If it returned Class, it would be the only appearance of Class in the new Type interfaces.
The real problem is the mixing of Class and Type. Previously, all types are represented in Class. It was already messy, but still tolerable. There weren't very many types.
With the new generic types, they should have designed a cleaner and true-to-specType hierarchy independent of Class. Instead they incorporated Class with Type and created more mess. The entire hierarchy just doesn't make sense. Anyone new to the subject and unaware of the history will be appalled by this nonsense.
I wouldn't hold the design of Type to a high standard. For example, ParameterizedType defines equals(), but not hashCode(). There's no way to have two implementations of ParameterizedType work in one hash map. And wildcard is also a type? Hell no.
And the name of the method getRawType() is just idiotic. It has nothing to do with raw type. It should be plainly named getClassOrInterface(). Would it be too verbose? Look at getActualTypeArguments() then. (And yeah, it returns actual arguments! Not fake ones!)
I was thinking about this, and I have a hunch. Perhaps they wanted to leave the possibility open for future craziness like this:
public class Z<L extends List<?>> {
L<Double> test;
}
This is not legal Java code, but I think it's clear what it would mean; new Z<ArrayList<?>>().test would be of type ArrayList<Double>.
If this were legal, ((ParameterizedType) test.getGenericType()).getRawType() would return a TypeVariable.
Sun's implementation of ParameterizedType has defined the getRawType() method to return Class<?>. So it clearly returns only Class<?>
However, on my classpath there are a few more implementations of ParameterizedType - from hibernate-validator, from aspectj, hibernate-annotations, jaxb. Some of them return Class<?>, some - Type. I don't know how they are used though.
There are other uses for the Type interface hierarchy than just the reflection api. For instance, a code generation library may define custom implementations. The JDK 8 itself has 3 different implementations of WildcardType. If ParameterizedType.getRawType() returned a Class instance, then you'd need to be able to create a Class instance whenever you want.
A Class is a very deeply-ingrained-in-the-JVM type that has bindings back to native-managed memory. To create a Class instance, you must have the byte code that defines the class. But in the case of a code generation library, the byte code doesn't even exist yet. If they had required the ParameterizedType to return a Class, it would limit the applicability of the Type interface hierarchy to only the reflection api.
This may not seem like a big deal, but neither is a cast.
ParameterizedType.getOwnerType() returns a Type as it may itself be either a Class or another ParameterizedType. It may in theory return a TypeVariable, as the following is valid Java:
<M extends Map<?,?>> M.Entry<?,?> first(M map) { ... }
However, it's compiled as a static reference to the type variable's erasure, in this case M.Entry would be compiled as Map.Entry. Instead of a TypeVariable, a call to getOwnerType() from the reflection api will be a Class, at least according to my tests.

Java: getting inner type in nested parameterized types (reflection)

Most of the documentation regarding type erasure handling in Java assumes that the use case is handling a type like SomeType<ParamType>.
I am trying to process method parameter for the following method:
public void setOtherReferenceRanges(List<ReferenceRange<T>> referenceRanges)
When the container class is instantiated with a type DvQuantity, this signature should become
public void setOtherReferenceRanges(List<ReferenceRange<DvQuanitity>> referenceRanges) in runtime.
Using reflection one can see that the List has an actualTypeArgument which is ReferenceRange<T>. Since reflection uses class information, I would not expect it to give me ReferenceRange<DvQuantity>.
However, when I created the class containing this method, I passed the DvQuantity type as T. So the type filling in T should be available to Java runtime, but I could not find a way of getting it. I end up with a TypeVariableImpl object accessed via reflection, which does not seem to contain any useful data.
Can you think of any ways to discover this information in runtime?
When you say
when I created the class containing this method
I guess you mean when you create an object of that type, for example:
foo = new ContainerClass<DvQuantity>();
In that case, because of erasure, there is no way to recover the type DvQuantity.
However, if you create a class passing a type parameter to the superclass, like this
class DvQuantityContainerClass extends ContainerClass<DvQuantity> {...}
...
foo = new DvQuantityContainerClass();
Or, shorter, an inline anonymous subclass (which looks almost like the first example but with a subtle but important difference):
foo = new ContainerClass<DvQuantity>(){};
Then you can recover the type parameter, because you recover the type parameter used to extend a superclass at runtime. Unfortunately, Java itself doesn't provide an easy way to now get the type of the DvQuantityContainerClass.setOtherReferenceRanges method with the T filled in. For that, I've written gentyref, to do advanced reflection on generic types:
Method m = DvQuantityContainerClass.class.getMethod("setOtherReferenceRanges", List.class);
// this will return List<ReferenceRange<DvQuanity>>, like you are lookingn for
return GenericTypeReflector.getExactParameterTypes(m, DvQuantityContainerClass.class)
Generic type information is erased by the compiler and is not available at runtime. When I need to ensure a certain type at runtime I pass in a class argument:
public <T> void doSomething(T t, Class<T> c);
This is not always convenient or even possible, but for many cases it is possible.
So the type filling in T should be available to Java runtime, but I could not find a way of getting it.
Perhaps it's not entirely correct, but the way I think about it is that at runtime there is no actual class - just an object without a specific type which meets the interface of T. In other words, erasure happens not with objects, but instead with these nebulous (in the OOP world at least) type-things.
http://java.sun.com/docs/books/tutorial/java/generics/erasure.html
There are ways of capturing the type information inside the class itself (T types would need a method getUnderlyingType()... or something), but that's a bad idea. If you truly need to raw type of the object, I'd reconsider using generics.

Java generics (type erasure)

Is it possible to something like:
Widget w = Gadet<Widget>().getInstance();
(Edit: getInstance invocation returns a newly created instance of the specified generic type parameter)
I do know about java's type erasure (atleast to some extent). But I got a little bit confused when i ran across
this.instanceClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
on hibernate.org
You want to pass in ANY class, and get an instance of that type -- statically, i.e. without reflection? Nope, that's not possible -- due to type erasure, right.
The only way to pass in ANY class is to pass it as a parameter:
Object getInstance(Class clz){ ... };
Even if you define it as
Object getInstance(Class<T> clz){ ... };
T is lost at runtime. All you have is class. I suppose language designers could make it sweeter by allowing things like:
new T()
which under the hood would do clz.newInstance(), but they didn't.
Hm ... to fully answer your question, a little background is required:
Erasure means that actual type parameters are not included in bytecode, and hence the dynamic type of a type parameter is unknown at runtime, making it generally impossible to instanciate it. (Which is why new T() for a type parameter T does not compile.)
However, actual type parameters specified in declarations of fields, methods or classes are recorded in the class file, and available to reflection. Under certain circumstances, the latter information is sufficient to determine to value of the type parameter.
For instance, the snippet from the hibernate website, if declared in class C<T>, infers the actual type of T if getClass() is a direct and non-generic subclass of C, by reflecting on the extends clause of that class' declaration. (If that extends clause however contained another type variable as in class D<T> extends C<T>, the method would throw a ClassCastException when attempting to cast a type variable to Class<?>).
If is possible to generalize that snippet to work for any non-generic getClass() (direct or otherwise), but if getClass() is generic the limited information the runtime retains about type parameters is insufficient to determine the type.
You could do something like the following:
public static <T> T getInstance(Class<T> klass) {
try {
return klass.newInstance();
} catch (Exception ex) {
//Do some real error handling here probably
return null;
}
}

Categories

Resources