首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与类型铸造相关的JLS

与类型铸造相关的JLS
EN

Stack Overflow用户
提问于 2016-01-10 11:19:45
回答 1查看 148关注 0票数 1

我试图从根本上理解Java中的类型转换,但无法理解JLS的某些部分。

特别是(从S类到类或接口类型T的转换):

此外,如果存在T的超型X和S的超型Y,使得X和Y都是明显不同的参数化类型(§4.5),并且X和Y的擦除是相同的,则会发生编译时错误。

这(从界面类型S到最终类型T)的意思是:

否则,S要么是参数化类型,它是对某些泛型类型声明G的调用,要么是对应于泛型类型声明G的原始类型。然后,必须存在T的超级类型X,这样X就是G的调用,或者出现编译时错误。此外,如果S和X是明显不同的参数化类型,则会发生编译时错误.

也许有人能举出一些简单的例子来澄清这些摘录?

经过@ErickGHagstrom的一些考虑和指导,我想我可以澄清这两个棘手的JLS摘要。

萃取物1。

JLS说:

如果下列任何一种类型是正确的,则两个参数化类型可以证明是不同的:

  • 它们是不同泛型类型声明的参数化。
  • 它们的任何类型参数都是明显不同的。

以及:

如果下列其中一个参数为真,则两个类型参数可以证明是不同的:

  • 这两个参数都不是类型变量或通配符,而且这两个参数不是相同的类型。
  • 一个类型参数是类型变量或通配符,具有S的上限(根据捕获转换(§5.1.10),必要时是);另一类参数T不是类型变量或通配符;且既不具有{##**$$}}S <:\x}T <:\x=1/4.2、(2/4、4.10)。
  • 每个类型参数都是类型变量或通配符,具有S和T的上界(根据捕获转换,必要时来自捕获转换);且既不具有S_x_s_s_\_

因此,List<Integer>List<Number>是明显不同的,但是List<? extends Integer>List<? extends Number>不是(所有列出的类型都有相同的擦除)。

关键是,两个明显不同的参数化类型与相同的擦除之间的子类型之间的关系是不可能的。

两个明显不同的参数化类型之间的子类型之间的关系与相同的擦除也是不可能的。如果S <: List<Integer>T <: List<Number>的话,那么(T)S(S)T在理论上都是不可能的。所以编译器抱怨。

萃取物2。

下面是我提出的示例(编译和运行没有错误):

代码语言:javascript
复制
    static final class T extends ArrayList<Number>{
    }

    static T t;

    static List<?> l1 = new T();
    static List<? extends Number> l2 = new T();
    static List<String> l3;

    public static void main(String[] args) {
        t = (T)l1;
        t = (T)l2;
//        t = (T)l3; //error
    }

您可以看到,List<?>List<? extends Number>可以转换为最终的T,而T没有(也不能)实现任何这些接口。

T <: List<Number>List<Number>是对List<E>的调用,如List<?>List<? extends Number>List<Number>List<?>List<? extends Number>并没有明显的区别(见上文)。

如果我们想将参数化接口类型S转换为最终类类型T,则T 不需要显式或隐式地实现S。但是这个T 必须来实现另一个参数化接口类型,该接口类型是与S的子类型关系。关键是参数化类型之间的子类型关系不仅是通过扩展或实现来定义的,而且也是通过包含类型参数的类型来定义的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-10 11:46:05

第一种情况:

ArrayList<String>ArrayList<Integer>具有相同的擦除功能,ArrayList,但是可以证明它们是不同的,因为没有String可以转换为Integer,也没有Integer可以转换为String

第二种情况:

设G为List<T>,S为List<String>。假设我有一个类似于这样的类MyFinalArrayList

代码语言:javascript
复制
public final class MyFinalIntArrayList extends ArrayList<Integer> {
    ...
}

另一个类似的

代码语言:javascript
复制
public final class MyFinalStrArrayList extends ArrayList<String> {
    ...
}

我可以将第一个转换为List<Integer,第二个可以转换为List<String,但反之亦然。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34704768

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档