views:

167

answers:

2

If I have this class:

class Foo<T> implements SomeInterface
{
    final private List<T> list = new ArrayList<T>();
    final private Class<? extends T> runtimeClass;

    public Foo(Class<? extends T> cl) { this.runtimeClass = cl; }

    // method override from SomeInterface
    @Override public boolean addChild(Object o)   
    {
        // Only add to list if the object is an acceptible type.
        if (this.runtimeClass.isInstance(o))
        {
            list.add( /* ??? how do we cast o to type T??? */ );
        }
    }

    public List<T> getList() 
    { 
        return this.list; 
    } // yes, I know, this isn't safe publishing....
}

how would I perform a runtime cast from Object to type T?

+5  A: 

Use this:

list.add(this.runtimeClass.cast(o))

See Class.cast() for details

Joachim Sauer
huh. that seems weird somehow... I am casting up from Object to something that extends T, then downcasting to T when it gets added to the list....
Jason S
If that is a concern, then make runtimeClass Class<T> instead of Class<? extends T>. That would ensure that all instances of T would be added to the list, not just instances of runtimeClass, because runtimeClass would be T.
ILMTitan
@Jason: if that seems weird, then your initial .isInstance() check is weird for exactly the same reason: why would you want to check if the value is some type that extends T instead of checking for T directly? And if you in fact check for `runtimeClass`, then casting to anything *but* `runtimeClass` is certainly on the weird side.
Joachim Sauer
+1  A: 
// method override from SomeInterface    
@Override public boolean addChild(Object o)       
{        
     // Only add to list if the object is an acceptible type.        
     if (this.runtimeClass.isInstance(o))        
     {            
         list.add((T)o);        
     }    
}
James
This code will produce a warning. While the code should never throw a ClassCastException (as long as no other ugly casting is done), it is still better to avoid that warning by using Class.cast().
Joachim Sauer
You can use the @SuppressWarnings("I am sure this is of Type T") to ignore the warning, but I do agree its not really 100% safe.
James