具有相同泛型参数的重载方法?
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>
我知道这是因为 T
和 S
都可以扩展相同的 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);
}
那么,我的问题是,有没有什么方法可以告诉编译器 T
和 S
从不同的 class 扩展而来,而不用具体说明是哪一个?我的意思是,在最后一种情况下,我指定了哪些 classes 必须是 T
和 S
(分别扩展)。但是如果我想要它更通用而不指定它们怎么办?我想告诉编译器,"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);
}
但是没有特定的界限,重载方法应该生成什么样的擦除字节码?
所以您的 T
和 S
在子类型 上 不同并不重要。重要的是已知的声明边界,它被翻译成超类型 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 层次结构的复杂程度。
更简单:给方法不同的名称。
我知道我不能这样做:
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>
我知道这是因为 T
和 S
都可以扩展相同的 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);
}
那么,我的问题是,有没有什么方法可以告诉编译器 T
和 S
从不同的 class 扩展而来,而不用具体说明是哪一个?我的意思是,在最后一种情况下,我指定了哪些 classes 必须是 T
和 S
(分别扩展)。但是如果我想要它更通用而不指定它们怎么办?我想告诉编译器,"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);
}
但是没有特定的界限,重载方法应该生成什么样的擦除字节码?
所以您的 T
和 S
在子类型 上 不同并不重要。重要的是已知的声明边界,它被翻译成超类型 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 层次结构的复杂程度。