将一种类型转换为另一种类型

4
我需要改进这段代码:
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);
}

因此,我决定实现一个类似Transformer的功能,将类型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;
  }
}

(String 转 Integer 的示例)

现在,为了转换类型,我有另一个名为 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)

因为我使用 ? 将它们存储在映射中,所以我陷入了困境。我不知道如何解决这个问题。我有一种感觉,这是不可能的,但我发帖想看看我是否错了。

我阅读了 Spring 的 这篇文章,但那是另一种方式。

1个回答

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)));
}

然而,由于其本质,代码无法保证类型安全。您需要确保放入Table中的3个元素是兼容的。


哦,我明白你做了什么。我没有想到会有类似的方法。现在它可以编译了。我会测试一下,谢谢。 - kMuller
它会工作,但如果你搞砸了转换器表,那么你将会得到运行时的ClassCastExceptions。 - Crazyjavahacking
那就没问题了,因为这意味着创建实现的程序员未能实现方法。因为实例和表是通过反射填充的(读取getSourceClass/getDestinationClass)。 - kMuller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接