I have been working on Google AdWords and came across this code
adwords-api-6.4.0, com.google.api.adwords.lib.AdWordsUser
public <T extends java.rmi.Remote> T getService(AdWordsService service) throws ServiceException {
try {
return (T) AdWordsServiceFactory.generateSerivceStub(service, this,
service.getEndpointServer(this.isUsingSandbox()), false);
} catch (ClassCastException e) {
throw new ServiceException("Cannot cast serivce. Check the type of return-capture variable.", e);
}
}
which is invoked like this:
AdWordsUser user = new AdWordsUser();
AdGroupServiceInterface adGroupService = user.getService(AdWordsService.V200909.ADGROUP_SERVICE);
Could you please explain how generics work in getService method? How is the return type determined?
What is the purpose of such usage? It doesn't seem like it provides type safety.
Does this usage have a specific name (so I could find more info on it and change the question title)?
A compiler may often infer the return type from the calling context. In the example provided, the compiler infers that the generic type is AdGroupServiceInterface because the result is being assigned to that type. If no context is available from which the return type can be inferred, it must be specified explicitly:
user.<AdGroupServiceInterface>getService(svc);
However, the getService method is not type-safe. Even though it contains a cast, this is only ensuring that the result implements the java.rmi.Remote interface. Because of type erasure in Java generics, the exact type T is not known, and the cast can't check to make sure that the result is AdGroupServiceInterface.
That's why a compiler will warn about the unsafe cast—a ClassCastException will be raised when the result is assigned to the AdGroupServiceInterface variable, not inside the method and its catch block.
I know more about C# than Java, but I'd guess that the getService method takes a parameter of type AdWordsService, and returns a type T, which must derive from java.rmi.Remote.
Presumably the AdWordsServiceFactory.generateSerivceStub method return type is of type java.rmi.Remote or similar, so it would be legal to cast this into the T type.
In C#, generics are used in this way to avoid casting, but the casting's still taking place here. I guess with this particular method, it's saving you from having to cast to your desired type, by making you tell the generic method exactly what type you want back.
I would also imagine that you need to specify the type of T in your call to getService. Maybe like this?
AdGroupServiceInterface adGroupService = user.getService<AdGroupServiceInterface>(AdWordsService.V200909.ADGROUP_SERVICE);
Related
Could you please help me to understand the generic concept here.
// Can't create an instance of T.
class Gen<T> {
T ob;
Gen() {
ob = new T(); // Illegal!!!
}
public static void main() {
Gen<Integer> genobj = new Gen<Integer>(); //Error
}
}
When your Java code is compiled, all generic type
information is removed (erased). This means replacing type parameters with their bound
type, which is Object if no explicit bound is specified, and then applying the appropriate
casts (as determined by the type arguments) to maintain type compatibility with the types
specified by the type arguments. The compiler also enforces this type compatibility.
My question:-Why java complier is throwing error here ?
Bevause after complitaion .
Thanks
There are a few ways that may work out here:
From a logical POV:
It's not even guaranteed that whatever template-parameter T you use has a default-constructor. Which obviously offers the problem of how to handle the absence of a default-constructor. Possible solutions would be to produce a runtime-error, compile-time error or disallow any T that doesn't provide a default-constructor. The latter would obviously break the template-definition, which allows any T. And the runtime-error would complicate things quite a bit and yield the same problem as mentioned above. Remains preventing this behavior in the first place and throwing a compile-time error.
From a internal view:
Let's assume we could use the provided code. Then how would it work? Due to erasure, new T() would produce an Object. But what if T is Integer? Well, we're screwed. An Object is not an Integer, so we'll get a plain class-cast exception.
So in summary: allowing the above to compile wouldn't work from a practical POV and in addition break the current definition of generics in java.
IMy question concerns the behavior of type casting with dynamic proxy and java generics. More specifically, I want to instrument a servelet object using dynamic proxy. For better reusability, I adopted some generic code template for creating proxy objects as below.
#SuppressWarnings("unchecked")
public static <T> T instrument(final T aT) {
T proxy = (T) Proxy.newProxyInstance(aT.getClass().getClassLoader(), new Class[]{MyServelet.class}, new InvocationHandler() {
#Override
public Object invoke(Object aProxy, Method aMethod, Object[] aArgs) throws Throwable {
..... instrumentation logic goes here
}
});
System.out.println("proxy class " + proxy.getClass());
System.out.println("input class " + aT.getClass());
return proxy;
}
Here T is my concrete servelet implementation class that implements MyServelet Interface. However, If I run the above method it prints out
proxy class class com.sun.proxy.$Proxy0
input class class MyServeletImplementation
So I wonder what happened to the type casting statement in the code snippet. It seems like it quietly failed since the proxy didn't get casted to MyServeletImplementation, but it didn't throw ClassCastException either. Can somebody shed me some light on this? Thanks!
No cast took place in the actual compiled bytecode of the method, because of type erasure.
When generating bytecode, the compiler treats any variable of a parameter type as having the same type as that parameter type's upper bound, or Object if the type is unbounded. So if T in your method had the constraint <T extends MyServelet>, the compiler would have treated proxy as a variable of type MyServelet, and inserted a cast. However, as T is unbounded, it's treated as a variable of type Object - thus, no cast.
The point of the dynamic proxy is that you don't care about the actual class of the proxy that is being returned. You just care that it implements all desired and specified interfaces.
The Javadocs for newProxyInstance state:
Returns:
a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces
So, newProxyInstance returned an instance of com.sun.proxy.$Proxy0 (whatever that is, we don't really care), but it also made sure that it's a MyServelet. You should be able to cast it to MyServelet without a ClassCastException, because newProxyInstance created the class to implement that interface, and you specified that it should by passing in new Class[]{MyServelet.class}.
For type casting not to have failed, Java generics must have inferred that T is MyServelet, not MyServeletImplementation. Perhaps when you called instrument, you did so like this:
MyServelet proxy = YourClass.instrument(new MyServeletImplementation());
So the cast was to MyServelet which should succeed, and not to MyServeletImplementation, which should fail.
The reason you needed to add #SuppressWarnings("unchecked") is because the compiler was trying to warn you that you were doing something wrong. by adding the suppression, you told the compiler that you didn't care because you knew what you were doing. maybe you shouldn't have added the annotation if you didn't uderstand why you were getting the warning in the first place?
Hint: the generic cast T proxy = (T) gets turned into Object proxy = (Object) by the compiler. ("Type Erasure" as mentioned in another answer).
Is it possible to declare the type of a generic using a class object?
For instance, I would like to do something like this:
Class returnType = theMethod.getReturnType();
AttributeComponent<returnType> attComponent;
attComponent = new AttributeComponent<returnType>(returnType, attName);
attributeComponents.put(methodName.substring(3), attComponent);
Now I know obviously this is incorrect, but is there a way to achieve this?
EDIT: explaining a little bit
I'm using reflection to go through all getters and then generate a UI element for each property (the AttributeComponent class, which has a JComponent element and a JLabel). I would like to use generics in order to create a getValue() method that would return an object of the property type.
I do not know if there is a way to compile something like that, but it has little value.
Think that thanks to type erasure, the compiled classes do not use the Generics information. That is, doing a Set<String> a = new Set<String>(); is useful for checking the use of a at compile time, but not at runtime.
So, you want to instantiate a Generic whose type will be only known at runtime, but at runtime it will not be used.
I would say this can be achieved by defining the method return type as generic; but you need to pass the actual type as a class argument to use it like you've shown:
<T> T yourMethod(Class<T> returnType) {
// use <T> as generic and returnType to refer to the actual T class
/* ... */ new AttributeComponent<T>(returnType, attName);
}
It would be also useful to see the larger context for what you're trying to do. If you want AttributeComponent.getValue() to return some generic type T (which is the method return type), that's completely useless unless you know each method return type at compile time, otherwise T will be nothing more than an Object. In my example above, you call yourMethod with a class that you already know and the same type will be returned (or some AttributeComponent of that type or whatever).
This question already has answers here:
When should I use the java 5 method cast of Class?
(5 answers)
Java Class.cast() vs. cast operator
(8 answers)
Closed 4 years ago.
I recently stumbled upon a piece of code that went like this:
Object o = .. ;
Foo foo = Foo.class.cast(o);
I was actually not even aware that java.lang.Class had a cast method, so I looked into the docs, and from what I gather this does simply do a cast to the class that the Class object represents. So the code above would be roughly equivalent to
Object o = ..;
Foo foo = (Foo)o;
So I wondered, why I would want to use the cast method instead of simply doing a cast "the old way". Has anyone a good example where the usage of the cast method is beneficial over doing the simple cast?
I don't think it's often used exactly as you have shown. Most common use I have seen is where folks using generics are trying to do the equivalent of this:
public static <T extends Number> T castToNumber(Object o) {
return (T)o;
}
Which doesn't really do anything useful because of type erasure.
Whereas this works, and is type safe (modulo ClassCastExceptions):
public static <T extends Number> T castToNumber(Object o, Class<T> clazz) {
return clazz.cast(o);
}
EDIT: Couple of examples of use from google guava:
MutableClassToInstanceMap
Cute use in Throwables#propagateIfInstanceOf, for type safe
generic throw spec
In Java there is often more than one way to skin a cat. Such functionality may be useful in cases where you have framework code. Imagine a method which accepts a Class object instance and an Object instance and returns the Object case as the class:
public static void doSomething(Class<? extends SomeBaseClass> whatToCastAs,Object o)
{
SomeBaseClass castObj = whatToCastAs.cast(o);
castObj.doSomething();
}
In general, use the simpler casting, unless it does not suffice.
In some cases, you only know the type to cast an object to during runtime, and that's when you have to use the cast method.
There is absolutely no reason to write Foo.class.cast(o), it is equivalent to (Foo)o.
In general, if X is a reifiable type, and Class<X> clazz, then clazz.cast(o) is same as (X)o.
If all types are reifiable, method Class.cast() is therefore redundant and useless.
Unfortunately, due to erasure in current version of Java, not all types are reifiable. For example, type variables are not reifiable.
If T is a type variable, cast (T)o is unchecked, because at runtime, the exact type of T is unknown to JVM, JVM cannot test if o is really type T. The cast may be allowed erroneously, which may trigger problems later.
It is not a huge problem; usually when the programmer does (T)o, he has already reasoned that the cast is safe, and won't cause any problem at runtime. The cast is checked by app logic.
Suppose a Class<T> clazz is available at the point of cast, then we do know what T is at runtime; we can add extra runtime check to make sure o is indeed a T.
check clazz.isInstance(o);
(T)o;
And this is essentially what Class.cast() does.
We would never expect the cast to fail in any case, therefore in a correctly implemented app, check clazz.isInstance(o) must always succeed anway, therefore clazz.cast(o) is equivalent to (T)o - once again, under the assumption that the code is correct.
If one can prove that the code is correct and the cast is safe, one could prefer (T)o to clazz.cast(o) for performance reason. In the example of MutableClassToInstanceMap raised in another answer, we can see obviously that the cast is safe, therefore simple (T)o would have sufficed.
class.cast is designed for generics type.
When you construct a class with generic parameter T, you can pass in a
Class. You can then do the cast with both static and dynamic
checking, which (T) does not give you. It also doesn't produce unchecked
warnings, because it is checked (at that point).
The common sample for that is when you retrieve from persistent layer a collection of entity referenced with a Class Object and some conditions. The returned collection could contain unchecked objects, so if you just cast it as pointed G_H, you will throw the Cast Exception at this point, and not when the values are accessed.
One example for this is when you retrieve a collection from a DAO that returns an unchecked collection and on your service you iterate over it, this situation can lead to a ClassCastException.
One way to solve it, as you have the wanted class and the unchecked collection is iterate over it and cast it inside the DAO transforming the collection in a checked collection and afterwards return it.
Because you might have something this:
Number fooMethod(Class<? extends Number> clazz) {
return clazz.cast(var);
}
A "cast" in Java, e.g. (Number)var, where the thing inside the parentheses is a reference type, really consists of two parts:
Compile time: the result of the cast expression has the type of the type you cast to
Run time: it inserts a check operation, which basically says, if the object is not an instance of that class, then throw a ClassCast Exception (if the thing you're casting to is a type variable, then the class it checks would be the lower bound of the type variable)
To use the syntax, you need to know the class at the time you write the code. Suppose you don't know at compile-time what class you want to cast to; you only know it at runtime.
Now you would ask, then what is the point of casting? Isn't the point of casting to turn the expression into the desired type at compile time? So if you don't know the type at compile time, then there is no benefit at compile-time, right? True, but that is just the first item above. You're forgetting the runtime component of a cast (second item above): it checks the object against the class.
Therefore, the purpose of a runtime cast (i.e. Class.cast()) is to check that the object is an instance of the class, and if not, throw an exception. It is roughly equivalent to this but shorter:
if (!clazz.isInstance(var))
throw new ClassCastException();
Some people have mentioned that Class.cast() also has a nice return type that is based on the type parameter of the class passed in, but that is just a compile-time feature that is provided by a compile-time cast anyway. So for that purpose there is no point in using Class.cast().
I would like to be able to detirmine the return type of my method call at runtime, but I can not seem to be able to get the Type of T.
public <T> T getT()
{
Object t = null;
Class<?> c = t.getClass();
System.out.println(c.getName());
return (T) t;
}
Is there any way to determine the Type of T at runtime in Java?
Your function will throw a NullPointerException, because you call "getClass" on a null pointer (since t is initialized with null). Additionally, generics are used for giving added compile-time type-checking. They do not give you anything special at runtime; generics simply use type Object, but cause the code which uses the generic object to perform implicit casts and also causes the compiler to be aware of how you will use it.
Java generics are a static type checking feature. Attempting to retrieve reflection artifacts from generic parameters is typical of poorly thought out design.
In the question example, there is no guarantee that T is a class or even interface. For example
List<? extends Frogs> list = thing.getT();
If you really want to go down this path (and I strongly suggest you don't, not that I expect you to take any notice), then you can supply a reflection object that is statically related to the generic parameter as an argument:
public <T> T getT(Class<T> clazz) {
Object value = map.get(clazz);
return clazz.cast(value);
}
If you have a generic Class you can write a constructor that takes the type and saves it into a member of your class. This way you can check the Type during runtime. All information that are only in the generics are gone after compiling.