【问题标题】:How to pass Object object in functional interface/lambda call如何在功能接口/ lambda 调用中传递 Object 对象
【发布时间】:2017-08-18 16:18:42
【问题描述】:

所以,我有一段代码是这样的

public static void printStuff(Object[] stuffs, Function<?, String> func) {
    for(Object stuff : stuffs) {
        String stringStuff = func.apply(stuff);
        System.out.println(stringStuff);
        // or whatever, what is done with that String is not relevant
    }
    // ...

这个方法要调用不同类型的数组,对应的func值,例如:

printStuff(arrayOfClasses, (Class<?> c) -> c.getSimpleName());
printStuff(arrayOfStrings, (String s) -> '"' + s + '"');
printStuff(arrayOfObjects, o -> o.toString());

所以我绝对需要我的 stuffsObject[],因为它是方法调用中不同类型的第一个公共超类。

在编译时,我得到:

MyClass.java:6: error: incompatible types: Object cannot be converted to CAP#1
        String stringStuff = func.apply(stuff);
                                        ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?

我的猜测是 javac 对我给Function&lt;?, String&gt; 调用的参数咆哮,其类型Object 不是extend Object

所以我的问题是,如何将Object 参数传递给Function&lt;?, String&gt;

我可以将接口类型更改为&lt;Object, String&gt;,但它会中断我的其他调用(使用Class[]String[] 等),这意味着几乎失去了通用性的全部意义,不是吗?

除非有某种方法可以将我的 stuffs 类型更改为 &lt;? extends Object&gt;[] 或泛型类型,而且我很确定这是不可能的。

提前谢谢各位。

编辑:

如果我将方法更改为通用方法,

public static <U> void printStuff(Object[] stuffs, Function<U, String> func) {

我仍然收到编译错误:

MyClass.java:6: error: method apply in interface Function<T,R> cannot be applied to given types;
            String stringStuff = func.apply(stuff);
                                     ^
  required: U
  found: Object
  reason: argument mismatch; Object cannot be converted to U

【问题讨论】:

  • 你不能public static &lt;T&gt; void printStuff(T[] stuffs, Function&lt;T, String&gt; func) {吗??
  • explanation
  • 不,唉。查看我的编辑
  • 您没有按照 RC 的建议更改您的签名。
  • @Maaaatt 哎呀,读得太快了。确实有效——只要我不忘记更改内部for 循环的类型。 Daaang,我很确定类型变量数组是不可能的

标签: java generics lambda functional-interface


【解决方案1】:

一种解决方案是使用:

public static <T> void printStuff(T[] stuffs, Function<T, String> func) {
    for(T stuff : stuffs) {
        // ....

【讨论】:

  • 你成功了。谢谢!
【解决方案2】:

至于第一个代码:

public static void printStuff(Object[] stuffs, Function<?, String> func) {
    for(Object stuff : stuffs) {
        String stringStuff = func.apply(stuff);
        System.out.println(stringStuff);
        // or whatever, what is done with that String is not relevant
    }
}

您收到此错误

MyClass.java:6:错误:不兼容的类型:对象无法转换为 CAP#1

您会收到该错误,因为 ? 可能是任何更具体的类,例如您还可以传递Function&lt;String, String&gt; 类型的参数func。

你可以通过声明签名来解决这个问题

public static void printStuff(Object[] stuffs, Function<Object, String> func)

或以一般方式:

public static <U> void printStuff(U[] stuffs, Function<? super U, String> func) {
    for(U stuff : stuffs) {
        String stringStuff = func.apply(stuff);
        System.out.println(stringStuff);
        // or whatever, what is done with that String is not relevant
    }
}

数组的类型必须等于Function 的第一个类型参数(或其子类)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 2021-07-14
    • 1970-01-01
    相关资源
    最近更新 更多