具有相同泛型参数的重载方法?

overload method with same generic parameter?

我知道我不能这样做:

public abstract class DTODomainTransformer<T, S> {

    public abstract S transform(T);

    public abstract T transform(S);

} 

因为我收到编译器投诉:

Method transform(T) has the same erasure transform(Object) as another method in type Transformer<T,S>

我知道这是因为 TS 都可以扩展相同的 class。所以这样做我可以告诉他 "No, they are not the same, so take it easy"

public interface Transformer<T extends AbstractDTO , S extends AbstractDomain> {

    public abstract S transform(T object);

    public abstract T transform(S object);

}

那么,我的问题是,有没有什么方法可以告诉编译器 TS 从不同的 class 扩展而来,而不用具体说明是哪一个?我的意思是,在最后一种情况下,我指定了哪些 classes 必须是 TS(分别扩展)。但是如果我想要它更通用而不指定它们怎么办?我想告诉编译器,"Hey, compiler, T and S are not the same! They are different classes. I don't know exactly which classes they are, but I'm sure that they are different".

没有明显的方法。 (尽管您可以构建一个,如下所示。)

此重载规则是由于声明重载的超类型(在本例中为接口)如何转换(通过擦除)为字节码的限制。

如果声明了泛型参数T,在其签名中使用T的方法将生成字节码作为T的上限,例如

class Generic<T> {
    void work(T t) {}
}

将被删除到

class Generic {
    void work(Object t) {}
}

class Generic<T extends Number> {
    void work(T t) {}
}

将被删除到

class Generic {
    void work(Number t) {}
}

这就是有界示例的工作方式,因为重载的擦除方式不同。

public interface Transformer {
    public abstract AbstractDomain transform(AbstractDTO object);
    public abstract AbstractDTO transform(AbstractDomain object);
}

但是没有特定的界限,重载方法应该生成什么样的擦除字节码?

所以您的 TS 在子类型 上 不同并不重要。重要的是已知的声明边界,它被翻译成超类型 class.

的擦除字节码

一个可能的解决方案是使用标记界面。

interface TransformT {}
interface TransformS {}
interface Transformable extends TransformT, TransformS {}

interface Transformer<T extends TransformT, S extends TransformS>
    T transform(S s);
    S transform(T t);
}

abstract class AbstractDTO implements Transformable {}
abstract class AbstractDomain implements Transformable {}

new SomeTransformerImpl<AbstractDTO, AbstractDomain>()

但我不一定推荐这样做。虽然有趣,但对我来说似乎很复杂。这取决于实际 class 层次结构的复杂程度。

更简单:给方法不同的名称。