Javavar推导因泛型而失败

考虑以下示例:

import java.lang.System;

interface Copy {
    
}

class Impl implements Copy {
    
    public <T extends Copy> T copy() {
        return (T)new Impl();
    }
    
    public void method() { System.out.println("hello"); }
    
}

public class MyClass {
    public static void main(String args[]) {
      var impl = new Impl();
      impl.method();
      var copy = impl.copy(); // deduction fails here
      copy.method();
    }
}

有没有办法让它在仍然使用 var 的同时推断类型?

注意:如果我更换var copy = impl.copy();Impl copy = impl.copy();编译器得到它。

使用 OpenJDK 11.0.6 运行

回答

当您使用 时var,编译器无法推断类型,T并且在 Java 中泛型是编译时构造,并且在类型擦除的情况下,所有泛型语法在运行时都会被删除。如果您只想使用var,您可以明确指定泛型类型:

var copy = impl.<Impl>copy();

你也可以简单地写:

public Copy copy()
{
    return new Impl();
}

这引入了相同的约束T extends Copy

我不确定你到底想实现什么,但通常,接口是一个契约,它指定实现它的任何类必须包含该接口的所有方法。您的界面不包含任何方法,它只是一个标记界面,如Serializable. 如果你试图强制任何实现的类都Copy必须包含一个copy方法,那么接口必须定义这个方法的签名:

interface Copy {
    public Copy copy(); 
}

class Impl implements Copy {
    
    @Override
    public Impl copy() {
        return new Impl();
    }
    
    public void method() { System.out.println("hello"); }
}

class MyClass {
    public static void main(String[] args) {
      var impl = new Impl();
      impl.method();
      var copy = impl.copy(); 
      copy.method();
 
    }
}

Java 支持协变返回类型,因此您甚至不需要首先使用泛型。您可以观察到,在Impl我已经将方法定义为 aspublic Impl copy()并且它仍然有效,因为Implimplements Copy

此外,值得注意的是,您的copy()方法在技术上不会复制,它会返回一个新实例。您可能有意采取这种行为,但这可能会误导遇到您的代码的其他人。

接口的更好名称可能是Copyable.


以上是Javavar推导因泛型而失败的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>