29

Possible Duplicate:
Java Class.cast() vs. cast operator

I am unsuccessfully trying to find out what Class.cast() does or what it may be good for. At the same time I am wondering whether I can somehow cast an object via reflection.

First I thought something like the lines below might work:

Object o = "A string";
String str = Class.forName("java.lang.String").cast(object);

But without an explicit cast it does not work.

So what is the cast method of Class class good for? And is it somehow possible just with reflection to cast objects, so you find the object's class, use Class.forName on it and cast it somehow?

Jasperan
  • 2,154
  • 1
  • 16
  • 40
Jarek
  • 7,425
  • 15
  • 62
  • 89
  • There is a good explanation: [http://stackoverflow.com/questions/2092659/what-is-difference-between-class-forname-and-class-forname-newinstance][1] [1]: http://stackoverflow.com/questions/2092659/what-is-difference-between-class-forname-and-class-forname-newinstance – Pawel Jan 18 '12 at 22:44

4 Answers4

39

An example where is does work:

class Favorites {
    private Map<Class<?>, Object> map = new HashMap<Class<?>, Object>();

    public <T> T get(Class<T> clazz) {
        return clazz.cast(map.get(clazz));
    }

    public <T> void put(Class<T> clazz, T favorite) {
        map.put(clazz, favorite);
    }
}

which allows you to write:

Favorites favs = new Favorites();
favs.put(String.class, "Hello");
String favoriteString = favs.get(String.class);

The reason your code doesn't work is that Class.forName() returns a Class<?>, i.e. a class object representing an unknown type. While the compiler could possibly infer the type in your example, it can not in general. Consider:

Class.forName(new BufferedReader(System.in).readLine())

what's the type of this expression? Clearly the compiler cannot know what the class name will be at runtime, so it doesn't know whether

String s = Class.forName(new BufferedReader(System.in).readLine()).cast(o);

is safe. Therefore it requests an explicit cast.

Simeon Leyzerzon
  • 18,658
  • 9
  • 54
  • 82
meriton
  • 68,356
  • 14
  • 108
  • 175
5

The return type of Class.forName will be Class<? extends Object>. You want Class<? extends String>, for instance using String.class.

String str = String.class.cast(object);

Not very useful, until you start replacing String with some kind of interface type.

In any case, reflection is generally evil.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
4

You can avoid a warning e.g. with the following code:

public <T> T getObject(Class<T> type){
  Object o = getSomeObject();
  if (type.isInstance(o)){
     return type.cast(o);
  } else {
     return null;
  }
}

while the following code will raise a warning:

public <T> T getObject(){
  return (T) getSomeObject();
}
Puce
  • 37,247
  • 13
  • 80
  • 152
3

Class.forName will return a Class<?> type object. The cast method will return the type parameter of Class. Thus, in this case it'll return a ? (Object) type object.

You should try:

Class<String> strClass = (Class<String>) Class.forName("java.lang.String");
String str = strClass.cast(object);

See also Class.cast()

David Lantos
  • 670
  • 4
  • 8