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.