Java类型擦除和重载?

时间:2011-09-22 08:36:35

标签: java generics spring-mvc overloading type-erasure

任何人都可以用简单的术语解释为什么在下面的类中,当我传入String,Integer或UUID时,只使用以Object作为参数的方法重载?

public final class SkuHydratingConverter implements Converter<Object, Sku> {
    @Autowired
    private SkuService skuService;


    /**
     * Default implementation, that errs as we don't know how to convert from
     * the source type.
     */
    public Sku convert(Object source) throws IllegalArgumentException {
        throw new IllegalArgumentException("Could not convert to Sku");
    }


    public Sku convert(String source) throws IllegalArgumentException {
        return convert(Integer.valueOf(source));
    }


    public Sku convert(Integer source) throws IllegalArgumentException {
        return skuService.get(source);
    }


    public Sku convert(UUID source) throws IllegalArgumentException {
        return skuService.get(source);
    }
}

最初我想在一堂课中实施三次Converter<?, ?>,但我很快发现这是不可能的。

3 个答案:

答案 0 :(得分:4)

重载机制在编译时工作,也就是说,在编译类时决定调用哪个方法,而不是在运行程序时。

由于运行时类型(通常)在编译时不能知道,所以像这样的代码片段

Object o = "some string";
method(o);

将调用以method为参数的Object,因为Objecto的{​​{3}}。

(这与类型擦除或泛型无关。)

答案 1 :(得分:1)

您实际为Converter实现的方法只是转换(对象源),因为您在:

中提供了类型参数Object
Converter<Object, Sku>

另外两个带有String和UUID参数的转换方法只有在直接使用实例(而不是通过接口)时才能调用。这两种方法不会覆盖任何东西,它们会超载。

Converter con = new SkuHydratingConverter();
con.convert(new String());//calls convert(Object), it does not know about any other method

SkuHydratingConverter con2 = new SkuHydratingConverter();
con2.convert(new String()); //calls convert(String), because it is one with best matching type of argument.

答案 2 :(得分:0)

正如其他人所解释的那样,这与擦除无关,而是convert(Object source)在编译时受到约束的事实。如果你在每个之前放置一个@Override,你将在其余部分得到错误,表明只有那个方法覆盖了超类方法。

您需要的是运行时检查实际类型:

public Sku convert(Object source) throws IllegalArgumentException
{
    if (source instanceof String) {
        return convert((String) source);
    } else if (source instanceof ...) {
    } else // none match, source is of unknown type
    {
        throw new IllegalArgumentException("Could not convert to Sku, unsuported type " + source.getClass());
    }
}

}

其他convert方法应为private