有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有几个对象都实现了一个需要映射到的具体接口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<String> mapper = new Mapper<String>() {
    @Override
    public String process(Op1 op1) {
        return "1";
    }

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

问题

当我尝试将Op映射到字符串时:

Op op = new Op1();

String i = op.process(mapper);

进程的返回类型是对象,而不是字符串。如果我更改Op接口,删除泛型,代码的工作原理与预期的一样:

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

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


共 (1) 个答案

  1. # 1 楼答案

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

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

    为了在使接口本身成为泛型时实现这一点,只需要在Op变量上提供泛型类型参数。毕竟,一个Op1就是一个Op<String>

    Op<String> op = new Op1();