Java 8:Lambda函数和通配符泛型

8
我有以下的类
class Book implement Borrowable  {
    @Override
    public String toString(Function<? extends Borrowable
                            , String> format) {
          return format.apply(this);    
    }
}

这让我出现了错误,无法在此(图书对象)上使用“apply”操作。 我当前的格式化程序是:
 Function<Book, String> REGULAR_FORMAT = book -> "name='" + book.name + '\'' +
        ", author='" + book.author + '\'' +
        ", year=" + book.year;

我不想让Lambda函数变成这种类型:

Function<Borrowable, String>

如果我失去了Borrowable未公开的Book成员访问权限。

2个回答

8
< p > Function<? extends Borrowable, String> 类型表示可以接受某些扩展了 Borrowable 类型的函数。它并不意味着它可以接受 Book。可能最好的解决方案是为 Borrowable 引入泛型参数:

public interface Borrowable<T> {
    public String toString(Function<? super T, String> format);
}

在中指定它:

public class Book implements Borrowable<Book> {
    @Override
    public String toString(Function<? super Book, String> format) {
        return format.apply(this);
    }
}

它类似于Comparable接口的工作方式。


它起作用了。尽管我不理解你的解决方案是如何实现的。一个链接或更多的见解将非常有帮助。 - AbrahamDaniel
使用String toString(Function<? extends Borrowable, String> format);方法的问题在于,您可以使用类型为Function<Movie, String>的对象来提供参数,其中MovieBorrowable的子类。在这种情况下,调用函数上的format.apply(this)是不安全的,因为this是一本Book,而不是一部Movie? super Book表示函数可以具有类型为BookBook的超类(这里是Borrowable<Book>Object)的参数。因此,调用format.apply(this)是安全的,因为this是一本Book,它是Borrowable<Book>,也是Object - undefined

5
您可能正在寻找 Function<? super Book, String>Function<Book, String> 是一个有效的 Function<? extends Borrowable, String>,但是 Function<DVD, String> 也是。您的方法(toString)可能会使用 Function<DVD, String> 调用,但您不能将 this 传递给它,因为 this 不是 DVD
建议将参数类型更改为 Function<? super Book, String>

请注意,它被覆盖了,因此实际上是在“Borrowable”接口中定义的。 - Tagir Valeev
应该可以工作,因为 Function<? super Borrowable, String>Function<? super Book, String> 的子类型(是的,我认为我把它弄对了)。 - user253751
1
它不起作用。即使它们是兼容的,你也不能在子类型中覆盖指定不同参数类型的方法。只有返回类型和声明的异常可以缩小。 - Tagir Valeev
@TagirValeev 我以为它也允许扩大参数。显然不行。 - user253751
@immibis 缩小范围可能是有意义的。(也不允许) - ZhongYu
@bayou.io 对于参数来说,缩小范围是没有意义的。扩大范围则有意义。考虑以下代码:class A {void go(Number n);} class B extends A {@Override void go(Integer n);} class C {{A a = new B(); a.go(5.2);}} - user253751

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接