Java 重载具有相同泛型参数的方法?
我知道我不能这么做:Java 重载具有相同泛型参数的方法?,java,generics,Java,Generics,我知道我不能这么做: public abstract class DTODomainTransformer<T, S> { public abstract S transform(T); public abstract T transform(S); } 那么,我的问题是,有没有办法告诉编译器,T和S从不同的类扩展而不告诉具体的类?我的意思是,在最后一个例子中,我指定了哪些类必须是T和S(分别扩展)。但是如果我希望它更通用,而不是指定它们呢?我想告诉编译器,
public abstract class DTODomainTransformer<T, S> {
public abstract S transform(T);
public abstract T transform(S);
}
那么,我的问题是,有没有办法告诉编译器,
T
和S
从不同的类扩展而不告诉具体的类?我的意思是,在最后一个例子中,我指定了哪些类必须是T
和S
(分别扩展)。但是如果我希望它更通用,而不是指定它们呢?我想告诉编译器,“嘿,编译器,T
和S
是不一样的!它们是不同的类。我不知道它们到底是什么类,但我确信它们是不同的。”没有明显的方法。(尽管您可以构建一个,如下所示。)
此重载规则是由于声明重载的超类型(在本例中为接口)如何(通过擦除)转换为字节码的限制
例如,如果声明了一个泛型参数T
,则在签名中使用T
的方法将生成字节码作为T
的上限
class Generic<T> {
void work(T t) {}
}
及
这就是有界示例的工作方式,因为重载的擦除方式不同
public interface Transformer {
public abstract AbstractDomain transform(AbstractDTO object);
public abstract AbstractDTO transform(AbstractDomain object);
}
但是如果没有特定的界限,重载的方法应该生成什么被擦除的字节码
所以你的T
和S
在子类型上不同并不重要。重要的是已知的声明边界,它被转换为超类型类的已擦除字节码
一种可能的解决方案可以使用标记接口
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>()
接口转换{}
接口转换{}
接口可转换扩展了TransformT,TransformS{}
接口变压器
T变换;
S变换(T);
}
抽象类AbstractDTO实现可转换的{}
抽象类AbstractDomain实现可转换的{}
新的SomeTransformerImpl更简单:为方法指定不同的名称。不,如果不提供明确的边界,就无法做到这一点。程序员如何确保类的用户不会违反该规则,以防他/她使用原始类型?如果有帮助,您只需绑定其中一个<代码>
您确实应该为每个方向使用不同的方法名称。您可以使用Guavas类作为父类。它已经包含了您需要的内容,并且由于方法名称不同,您不必关心冲突的方法。
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);
}
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>()