由于泛型类中的类型不匹配而导致的编译错误

compilation error due to type mismatch in generic class

提问人:jumbo 提问时间:11/13/2023 最后编辑:AztecCodesjumbo 更新时间:11/15/2023 访问量:51

问:

法典:

public T orElseGet(Supplier<? super T> supplier) {
    if (this.isPresent()) {
        return this.get();
    } else {
        return castFromSupplier(supplier);
    }
}

private static <R> R castFromSupplier(Supplier<? super R> supplier) {
    return (R) supplier.get();
}

编译错误:

Maybe.java:74: warning: [unchecked] unchecked cast
return (R) supplier.get();

required: R
found: — CAP#1
where R is a type-variable:
R extends Object declared in method <R>castFromSupplier(Supplier<? super R>)
where CAP#1 is a fresh type-variable:
CAP#1 extends Object super: R from capture of ? super R
1 warning
Grading terminated.

问题本质上出在我创建的某个特定的泛型上下文中(其操作方式与其他上下文(如 Optional 或 Log)非常相似)。该方法实质上检查该值是否存在。如果它存在,它只返回值;否则,它将从输入供应商的方法中获取值。JavaorElseGetget

我不知道为什么我的代码在jshell中运行良好,没有编译错误,正确的输出,但只有在我必须提交此代码的这个平台中,它才会给我这个错误。有什么想法可以帮助我调试此错误语句吗?

Java 泛型 函数式编程

评论

0赞 Stultuske 11/13/2023
这是一个警告,而不是一个错误。为什么不问问你使用的平台的人呢?
4赞 Grinding For Reputation 11/13/2023
永远不要发布代码图片!将它们粘贴到此处使我们更容易;)
2赞 Mark Seemann 11/13/2023
请不要上传代码/数据/错误的图像。
0赞 AztecCodes 11/13/2023
我删除了代码屏幕截图并提取了代码。
0赞 Michael 11/13/2023
即使你的代码被编译了,它也没有意义。当您知道没有项目时,您正在调用第二条路径。它应该只是什么的。Supplier.getreturn null

答:

0赞 Thomas Kläger 11/15/2023 #1

你的意思可能是

public T orElseGet(Supplier<? extends T> supplier) {
    if (this.isPresent()) {
        return this.get();
    } else {
        return castFromSupplier(supplier);
    }
}

private static <R> R castFromSupplier(Supplier<? extends R> supplier) {
    return (R) supplier.get();
}

这与 Optional.orElseGet 一致:

public T orElseGet(Supplier<? extends T> supplier)

您的版本的问题在于

class SupplierTest {
    private static <R> R castFromSupplier(Supplier<? super R> supplier) {
        return (R) supplier.get();
    }

    public static void main(String... args) {
        Supplier<Object> so = Object::new;
        String s = castFromSupplier(so);
        System.out.println(s);
    }
}

编译(带有有关未经检查的强制转换的警告),但在运行时将失败并显示 a,因为供应商返回 an,但该方法需要来自 .ClassCastExceptionObjecttest()StringcastFromSupplier()