【问题标题】:When is the diamond operator, and when not?什么时候是钻石算子,什么时候不是?
【发布时间】:2021-06-29 09:08:11
【问题描述】:

考虑以下两行代码:

final List<Path> paths = new ArrayList<>();
final FileVisitor<Path> fv = new SimpleFileVisitor<>();

对我来说,它们看起来很相似。但是,Java 编译器 (1.8) 拒绝第二行并显示消息“无法推断 SimpleFileVisitor 的类型参数”。

谁能解释一下,有什么问题吗?

【问题讨论】:

  • SimpleFileVisitor() 构造函数受到保护。所以你不能这样称呼它。
  • 我收到错误“'SimpleFileVisitor()' has protected access in 'java.nio.file.SimpleFileVisitor'”。构造函数受到保护。你无法访问它。我怀疑删除钻石会使错误消失...所以我不确定您为什么认为问题出在钻石上。
  • 仍然是钻石运算符,因为你的问题的标题,我强调这一点。
  • 钻石运算符使用的自动类型推断也有一些限制。 Java 不能总是自动推断类型,有时您必须手动指定它。有时它可以推断它但它不是您想要的类型,那么您还必须手动指定它。在您的特定情况下,问题在于代码无效,因此 Java 也无法推断类型。所以这只是other issue的后续问题。

标签: java generics diamond-operator


【解决方案1】:

我不明白您是如何收到错误消息 Cannot infer type arguments 的,因为您的语法是正确的,除了正如许多人已经说过的那样,java.nio.file.SimpleFileVisitor 类只有一个构造函数 protected

protected SimpleFileVisitor() {
}

这意味着只有此类的子级才能初始化SimpleFileVisitor 的实例,这就是您的代码无法编译的原因。

我不知道这个类,但是通过快速查看代码,我猜他们只是希望您先扩展它(或使用来自其他地方的现有扩展),然后使用它来实现FileVisitor接口。

如果您没有要使用的具体子类并想创建自己的MySimpleFileVisitor

public class MySimpleFileVisitor<T> extends SimpleFileVisitor<T> {
    public MySimpleFileVisitor() {
        super(); //<-- here you have the right to call the protected constructor of SimpleFileVisitor
    }
}

...然后您将能够实例化您的类并使用已经实现的方法,如下所示:

FileVisitor<Path> fv = new MySimpleFileVisitor<>(); //<-- here you will be able to correctly infer parameter type as you do in your List example
fv.visitFile(file, attrs); //<-- here you enter the method implemented inside SimpleFileVisitor

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多