Java接口泛型,返回类型取决于参数generic

时间:2014-08-12 22:38:45

标签: java generics

我有几个对象都实现了需要映射到的具体接口 Op 任意类型。我正试图用双​​调度方法解决问题:

interface Mapper<R> {
    R process(Op1 op1);
    R process(Op2 op2);
}

interface Op<T>{
    <R> R process(Mapper<R> mapper);
}

class Op1 implements Op<String> {
    @Override
    public <R> R process(Mapper<R> mapper) {
        return mapper.process(this);
    }
}

class Op2 implements Op<String> {
    @Override
    public <R> R process(Mapper<R> mapper) {
        return mapper.process(this);
    }
}

我创建了一个mapper,其中包含指定 Ops 的方法,映射到 String

Mapper<String> mapper = new Mapper<String>() {
    @Override
    public String process(Op1 op1) {
        return "1";
    }

    @Override
    public String process(Op2 op2) {
        return "2";
    }
};

问题

当我尝试将 Op 映射到 String 时:

Op op = new Op1();

String i = op.process(mapper);

进程的返回类型是 Object 而不是 String 。如果我更改 Op 界面,删除泛型,代码就像预期的那样:

interface Op{
    <R> R process(Mapper<R> mapper);
}

为什么编译器不接受 Op 接口中的泛型定义?

1 个答案:

答案 0 :(得分:5)

Op1分配给Op类型的变量时,您使用的是原始类型。 Op是通用的,但您没有提供泛型类型参数,因此会发生类型擦除,返回类型为Object,而不是String。您确实创建了一个Op1 Op<String>,但在分配给原始Op时该信息会丢失。

当在方法而不是接口上声明泛型类型参数时,它起作用,因为类型推断接管并且R被推断为String

为了使接口本身具有通用性,只需要在Op变量上提供泛型类型参数。毕竟,Op1Op<String>

Op<String> op = new Op1();