gpt4 book ai didi

java - 为什么这个涉及通用接口(interface)方法的程序可以编译?

转载 作者:搜寻专家 更新时间:2023-11-01 01:42:33 24 4
gpt4 key购买 nike

以下代码在运行时抛出一个 ClassCastExceptionpublic String foo() { return "bar"; 行} 生成警告“found 'java.lang.String', required 'T'”。我理解 ClassCastException(调用接口(interface)方法时 T 等于 Integerfoo 返回一个 String) 并且我理解警告(它正试图警告我们这个问题)。但我不明白的是为什么程序会编译。为什么允许返回 String 的方法覆盖返回 T 的方法?

public class Main {

interface MyInterface {

<T> T foo();
}

static class MyClass implements MyInterface {

@Override
public String foo() { return "bar"; }
}

public static void main(String[] args) {
int a = ((MyInterface) new MyClass()).<Integer>foo();
}
}

最佳答案

天真地声明 <T> T foo(); 时编译器将尝试推断 foo 的结果类型从它将被分配的变量。这就是编译的原因。它可以很容易地测试:

interface MyInterface {
<T> T foo();
}

class MyClass implements MyInterface {
@Override
public String foo() { return "bar"; }
}

public class Main {
public static void main(String[] args) {
MyInterface myInterface = new MyClass();
//the result of foo will be String
String bar = myInterface.foo();
System.out.println(bar); //prints "bar"
try {
//the result of foo at compile time will be Integer
Integer fail = myInterface.foo();
System.out.println(fail); //won't be executed
} catch (ClassCastException e) {
//for test purposes only. Exceptions should be managed better
System.out.println(e.getMessage()); //prints "java.lang.String cannot be cast to java.lang.Integer"
}
}
}

并且编译时的结果不可能是Object .如果它是对象,那么您将必须添加手动类型转换,但事实并非如此。

简而言之,声明这样的方法是没有用的,只会给程序员带来困惑和困惑。

此方法声明在以下情况之一中变得有用:

  • 声明泛型时 <T>在接口(interface)/类的顶层:

    interface MyInterface<T> {
    T foo();
    }

    class MyClass implements MyInterface<String> {
    @Override
    //can only return String here. Compiler can check this
    public String foo() { return "bar"; }
    }
  • 通过时Class<T>作为参数,它使编译器能够推断结果类型并在不满足此条件时引发适当的编译器错误:

    interface MyInterface {
    <T> T foo(Class<T> clazz);
    }

    class MyClass implements MyInterface {
    @Override
    public <T> T foo(Class<T> clazz) {
    try {
    return clazz.newInstance();
    } catch (InstantiationException e) {
    e.printStackTrace(System.out);
    } catch (IllegalAccessException e) {
    e.printStackTrace(System.out);
    }
    return null;
    }
    }

    public class Main {
    public static void main(String[] args) {
    MyInterface myInterface = new MyClass();
    //uncomment line below to see the compiler error
    //Integer bar = myInterface.foo(String.class);

    //line below compiles and runs with no problem
    String bar = myInterface.foo(String.class);
    System.out.println(bar);
    }
    }

关于java - 为什么这个涉及通用接口(interface)方法的程序可以编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27711348/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com