Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么Java允许您强制转换到集合?_Java_Collections_Interface_Casting - Fatal编程技术网

为什么Java允许您强制转换到集合?

为什么Java允许您强制转换到集合?,java,collections,interface,casting,Java,Collections,Interface,Casting,我有一个简单的foo类,我能够在没有任何编译器错误的情况下转换到集合接口(映射Map或List)。 请注意,Foo类不实现任何接口或扩展任何其他类 public class Foo { public List<String> getCollectionCast() { return (List<String>) this; // No compiler error } public Map<String, Strin

我有一个简单的
foo
类,我能够在没有任何编译器错误的情况下转换到集合接口(映射
Map
List
)。 请注意,
Foo
类不实现任何接口或扩展任何其他类

public class Foo {

    public List<String> getCollectionCast() {
        return (List<String>) this;    // No compiler error
    }

    public Map<String, String> getCollection2Cast() {
        return (Map<String, String>) this;    // No compiler error
    }

    public Other getCast() {
        return (Other)this;     // Incompatible types. Cannot cast Foo to Other
    }

    public  static class Other {
        // Just for casting demo
    }

}
公共类Foo{
公共列表getCollectionCast(){
返回(列出)此;//没有编译器错误
}
公共地图getCollection2Cast(){
返回(映射)此;//没有编译器错误
}
公共其他getCast(){
返回(其他)this;//不兼容的类型。无法将Foo强制转换为其他类型
}
公共静态类其他{
//只是为了试演
}
}
当我尝试将
Foo
类强制转换为集合时,为什么Java编译器不返回不兼容类型错误


Foo
未实现
收集
。我预计会出现不兼容的类型错误,因为给定当前的
Foo
类签名,这不能是
集合

这不是因为它们是集合类,而是因为它们是接口
Foo
没有实现它们,但它的子类可以实现。所以这不是编译时错误,因为这些方法可能对子类有效。在运行时,如果
这个
不是实现这些接口的类,那么它自然是一个运行时错误


如果您将
List
更改为
ArrayList
,您也会因此得到一个编译器时间错误,因为
Foo
子类可以实现
List
,但不能扩展
ArrayList
(因为
Foo
没有)。类似地,如果您将
Foo
final
,编译器将为您的接口强制转换提供一个错误,因为它知道它们永远不会为真(因为
Foo
不能有子类,也不能实现这些接口)。

编译器不会阻止代码将类型强制转换为接口,除非它能确定这种关系是不可能的

如果目标类型是接口,那么它是有意义的,因为扩展
Foo
的类可以实现
Map
。但是,请注意,这只在
Foo
不是
最终版本时起作用。如果您使用
最终类Foo
声明类,则该转换将不起作用

如果目标类型是一个类,那么在这种情况下它将失败(尝试
(HashMap)this
),因为编译器肯定知道
Foo
HashMap
之间的关系是不可能的

为了便于参考,这些规则在(T=目标类型-
Map
,S=源类型-
Foo

如果T[目标类型]是接口类型:

  • 如果S不是最终类(§8.1.1),则如果存在T的超类型X和S的超类型Y,使得X和Y都是可证明不同的参数化类型,并且X和Y的擦除相同,则会发生编译时错误。
    否则,强制转换在编译时总是合法的(因为即使S没有实现T,S的一个子类也可能实现)。

  • 如果S是最终类(§8.1.1),则S必须实现T,否则会发生编译时错误

请注意引用文本中的粗体斜体注释。

所有超级界面: 收藏,可编辑


Foo是一个列表,也是一个集合。

您可以编写
Foo
的子类来实现
List
Map
@istovatis,因为
Other
是一个类,
Foo
的子类也不能扩展
Other
。在上面的问题中,有两个类实现了两个接口。在这里,foo类没有实现任何接口。此外,在您提供的问题中,编译器在一个接口强制转换中抱怨,而在另一个接口强制转换中没有抱怨。因此,我们必须处理两个不同的示例,不,
Foo
既不是
列表
也不是
集合