I have a method toString( Object )
which delegates the conversion to handlers. The handlers are defined like this:
public interface IToStringService<T> {
public String toString( T value );
}
The code looks like this:
// (1) How can I say that these two wildcards must in fact be the same type?
private Map<Class<?>, IToStringService<?>> specialHandlers = Maps.newHashMap();
// Generic method, must accept Object (any type really)
@Override
public String toString( Object value ) {
if( null == value ) {
return "null";
}
Class<?> type = value.getClass();
if( type.isArray() ) {
return arrayToString( value );
}
// (2) How can I get rid of this SuppressWarnings?
@SuppressWarnings( "unchecked" )
IToStringService<Object> handler = (IToStringService<Object>) specialHandlers.get( type );
if( null != handler ) {
return handler.toString( value );
}
return value.toString();
}
public <T> void addSpecialHandler( Class<T> type, IToStringService<T> handler ) {
specialHandlers.put( type, handler );
}
And one implementation looks like this:
@SuppressWarnings( "rawtypes" ) // Can't add generics to "Class" or I get compile errors when calling DefaultToStringService.addSpecialHandler() :-(
public class ClassToStringService implements IToStringService<Class> {
@Override
public String toString( Class value ) {
return value == null ? "null" : value.getName();
}
}
I have several problems here:
How can I say that the handlers in the
specialHandlers
map must match the type used as the key?How can I use the same information inside the method to avoid casting and
@SuppressWarnings
?When I change
ClassToStringService
to implementIToStringService<Class<?>>
, I get a compile error when callingaddSpecialHandler( Class.class, new ClassToStringService() );
How do I solve this?