Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重载具有相同泛型参数的方法?_Java_Generics - Fatal编程技术网

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>()