Unchecked Cast Warning when calling 'Class.forName'

My code is as follows

package com.foo; public class TestComposition { public static void main(String[] args) { try { Class<Foo> fooClass = (Class<Foo>) Class.forName("Foo"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } 

Assignment in a try block results in a warning indicating

 Type safety: Unchecked cast from Class<capture#1-of ?> to Class<Foo> 

Why is this?

+6
source share
4 answers

Itโ€™s good to start by making it clear where the problem is in the act itself. Here is a shorter example:

 public class Test { public static void main(String[] args) throws Exception { Object x = (Class<Test>) Class.forName("Test"); } } 

This problem still has the same problem. The problem is that the actor is not actually going to test anything, because the cast will be effectively converted to the raw Class type. For Class<T> this is somewhat more surprising, because the object actually knows the class, but consider a similar situation:

 List<?> list = ... get list from somewhere; List<String> stringList = (List<String>) list; 

This will not check if this is a List<String> , because this information is lost due to type erasure.

Now in your case there is actually a fairly simple solution - if you know the class name at compile time, just use:

 Class<Foo> fooClass = Foo.class; 

If you can provide a more realistic example where this is not the case, we can help you determine the most suitable alternative.

+7
source

First, if you know the exact class, you do not need Class.forName . Foo.class will do. (Prior to J2SE 5.0, Foo.class actually compiled to execute Class.forName("Foo") and then cache it in static.)

What you might want is something like:

 Class<? extends Foo> fooClass = (Class<? extends Foo>) Class.forName("MyFoo"); 

(When I say โ€œwant,โ€ throws and especially reflection are evil.)

As it happens, you have a suitable method to make the throw "safe" (assuming that Foo not shared). Itโ€™s safe, since it doesnโ€™t indicate a reference to an incompatible object, and not like there is no error in it or no unexpected exception.

 Class<? extends Foo> fooClass = Class.forName("MyFoo").asSubclass(Foo.class); 
+25
source

The runtime system does not know about generics, and therefore it can only verify that something is of type Class , and not if it is of type Class<Test> . This is what warns about.

To eliminate this warning, a method has been added to the Class class. You can use this instead of casting yourself: http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class )

+2
source

If you know the exact class, you will not need to use Class.forName

 Class<Foo> fooClass = Foo.class; 

This only makes sense when you don't know the type.

+1
source

Source: https://habr.com/ru/post/892221/


All Articles