Java 泛型接口转换

Posted

技术标签:

【中文标题】Java 泛型接口转换【英文标题】:Java Generics Interface casting 【发布时间】:2014-05-03 03:25:01 【问题描述】:

我偶然发现了一个涉及我不理解的泛型和接口的 Java 转换情况。

请考虑以下我创建List<Interface1> 的代码。然后 get() 一个元素并将其转换为 Interface2 不会出现编译器错误,尽管这两个接口完全不相关。

import java.util.*;

public class Main 
  public static void main(String ... args) 
    List<Interface1> list = new ArrayList<>();
    list.add(new Interface1() );

    Interface1 ok = list.get(0);
    Interface2 why = (Interface2)list.get(0);
  


interface Interface1 


interface Interface2 

谁能解释为什么在第二个get(0) 的转换没有编译器错误?

两个旁注:执行该类会抛出一个ClassCastException(如预期的那样)。而且使用两个类而不是接口确实会产生编译错误。

【问题讨论】:

【参考方案1】:

此行为与泛型无关:您可以将任何接口转换为任何其他接口而不会出现编译错误。

您不能对类执行此操作,因为 Java 可以在编译时检查一个类是否可以转换为另一个类。

但是,对于接口,转换可能会成功或失败,具体取决于实际实现接口的类。不过,这只能在运行时发现。

【讨论】:

【参考方案2】:

有可能,Interface1 的子类也可以是Interface2 的子类。所以,它不会给出编译错误。

【讨论】:

【参考方案3】:

如果你有一个实现Interface1 的类型,它也可以实现Interface2。因此编译器不会责怪你,因为在运行时转换可能会成功。

【讨论】:

【参考方案4】:

这不是一般问题。 JVM 对Interface1Interface2 之间的兼容性一无所知。所以你得到ClassCastException

【讨论】:

不正确,如果一个对象实现了这两个接口。 @SilviuBurcea 这里Interface1Interface2 两个不同的接口。 Silviu 的观点是,Interface1 和 Interface2 是不同的接口这一事实并不自动意味着实例化对象不会同时实现这两者。由于编译器不知道这一点,它将允许强制转换。 ClassCastException 发生是因为匿名类没有实现 Interface2。【参考方案5】:

这是因为 JAVA 支持多种接口实现。由于我们可以有任意数量的任何类型的类(任何父类)可以实现一个接口,JVM 设计是这样的,直到运行时,我们才能识别在该接口的位置传递哪种类型。所以可以有任何接口放置在数组列表

【讨论】:

【参考方案6】:

编译器不知道这不起作用:您可以有一个 Interface2 类型的实例,它也是 Interface1 类型的实例(例如:class ImplementingClass implements接口 1,接口 2)。那么演员阵容就好了。

“使用两个类而不是接口实际上会产生编译错误。”

在这种情况下,编译器知道它不会工作,因此在这种情况下您会遇到编译错误。

【讨论】:

以上是关于Java 泛型接口转换的主要内容,如果未能解决你的问题,请参考以下文章

Java泛型

java从基础知识泛型

Java 泛型概念相关面试题

java泛型——泛型类泛型方法泛型接口

java--泛型--泛型接口&泛型方法

Java泛型