2015-07-21 2 views
4

мне нужно улучшить этот код:Transform одного типа к другому

final String valueString = value.toString(); 

if (Path.class.isAssignableFrom(destinationType)) { 
    fixedValues.put(key, Paths.get(valueString)); 
} /* ... as above, for other types ... */ { 
} else { 
    fixedValues.put(key, valueString); 
} 

Так что я решил реализовать трансформатор типа, который преобразует тип X в другой Y.

Я создал этот интерфейс

public interface Converter<S, D> { 
    D convert(final S source); 

    Class<D> getDestinationClass(); 
    Class<S> getSourceClass(); 
} 

так, когда мне нужно осуществить преобразование я реализовать этот интерфейс

public class StringToIntegerConverter implements Converter<String, Integer> { 
    @Override 
    public Integer convert(final String source) { 
    return Integer.parseInt(source); 
    } 

    @Override 
    public Class<Integer> getDestinationClass() { 
    return Integer.class; 
    } 

    @Override 
    public Class<String> getSourceClass() { 
    return String.class; 
    } 
} 

(Пример строки -> Integer)

Теперь, чтобы преобразовать типы I имеют другой класс Converters, который содержит внутри таблицы (таблица Guava с двумя ключами), где хранятся все конвертеры.

private final static ImmutableTable<Class<?>, Class<?>, Converter<?, ?>> converters; 

И есть метод convert

public <S, D> D convert(final Class<S> source, final Class<D> destination, final S value) { 
    return destination.cast(converters.get(source, destination).convert(source.cast(value))); 
} 

Ошибка

incompatible types: S cannot be converted to capture#1 of ? 

на source.cast(value)

, потому что хранить их на карте с ? так я застрял. Я не знаю, как я могу это исправить. У меня появилось ощущение, что это невозможно, но я публикую, чтобы узнать, не ошибаюсь.

Я прочитал this к весне, но это другой способ

ответ

3

То, что вы пытаетесь достичь, это возможно:

@SuppressWarnings("unchecked") 
public <S, D> D convert(final Class<S> source, final Class<D> destination, final S value) { 
    final Converter<S, D> converter = (Converter) converters.get(source, destination); 

    return destination.cast(converter.convert(source.cast(value))); 
} 

Однако код по своей природе не может гарантировать безопасность типа. Вы должны гарантировать, что 3 элемента, помещенные в Table, совместимы.

+0

О, я понимаю, что вы сделали. Я не думал, что-то подобное. Теперь он компилируется. Теперь я тестирую его, спасибо – kMuller

+0

Он будет работать, но если вы испортите таблицу преобразователей, вы получите время выполнения ClassCastExceptions. – Crazyjavahacking

+0

Тогда все в порядке, потому что это означает, что программист, создавший реализацию, не смог реализовать методы. Поскольку instace и таблица заполнены отражением (чтение getSourceClass/getDestinationClass) – kMuller

Смежные вопросы