Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/336.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 参数化在Collections.EmptyList类中如何工作?_Java_Generics - Fatal编程技术网

Java 参数化在Collections.EmptyList类中如何工作?

Java 参数化在Collections.EmptyList类中如何工作?,java,generics,Java,Generics,我只是想知道执行后会发生什么: List List=Collections.emptyList() 以下是收集代码: public static final List EMPTY_LIST = new Collections.EmptyList(null); public static final <T> List<T> emptyList() { return EMPTY_LIST; } private static class EmptyLi

我只是想知道执行后会发生什么:
List List=Collections.emptyList()

以下是收集代码:

public static final List EMPTY_LIST = new Collections.EmptyList(null);
public static final <T> List<T> emptyList() {
        return EMPTY_LIST;
    }

private static class EmptyList<E> extends AbstractList<E> 
                                  implements RandomAccess, Serializable {

    private EmptyList() {
    }

    //...
}
public static final List EMPTY\u List=new Collections.EmptyList(null);
公共静态最终列表emptyList(){
返回空的_列表;
}
私有静态类EmptyList扩展了AbstractList
实现随机访问,可序列化{
私有空列表(){
}
//...
}
  • EmptyList
    没有带参数的构造函数时,如何调用
    EmptyList(null)

  • 请给我解释一下
    Collection
    的方法泛型
    T
    如何变成
    EmptyList
    的泛型
    E

  • 我只是想知道我执行后会发生什么

    没有发生任何事情,因为有关泛型和类型参数的一切都在编译时进行

    EmptyList
    没有带参数的构造函数时,如何调用
    EmptyList(null)

    这是不可能的,但是我看到的JDK代码没有通过将
    null
    传递给构造函数来创建空列表。不要相信反编译器代码

    请解释
    集合
    的方法泛型类型
    T
    如何变成
    EmptyList
    的泛型类型
    E
    的过程

    T
    是一个类型变量,它捕获在
    emptyList()
    的每个调用站点推断的类型。此变量被“传递”(在静态类型分析期间)到
    emptyList
    ,因此返回值的类型为
    List
    E
    EmptyList
    的类型参数的名称,该类型参数在该特定类型实例化中假定值为
    T
    。这非常类似于当您说
    new ArrayList()
    时,
    ArrayList
    E
    变成
    String

    我只是想知道我执行后会发生什么

    没有发生任何事情,因为有关泛型和类型参数的一切都在编译时进行

    EmptyList
    没有带参数的构造函数时,如何调用
    EmptyList(null)

    这是不可能的,但是我看到的JDK代码没有通过将
    null
    传递给构造函数来创建空列表。不要相信反编译器代码

    请解释
    集合
    的方法泛型类型
    T
    如何变成
    EmptyList
    的泛型类型
    E
    的过程

    T
    是一个类型变量,它捕获在
    emptyList()
    的每个调用站点推断的类型。此变量被“传递”(在静态类型分析期间)到
    emptyList
    ,因此返回值的类型为
    List
    E
    EmptyList
    的类型参数的名称,该类型参数在该特定类型实例化中假定值为
    T
    。这非常类似于当您说
    new ArrayList()

    您的反编译代码时,
    ArrayList
    E
    变成
    String

    public static final List EMPTY_LIST = new Collections.EmptyList(null);
    
    public static final <T> List<T> emptyList() {
        return EMPTY_LIST;
    }
    
    实际代码

    @SuppressWarnings("unchecked")
    public static final List EMPTY_LIST = new EmptyList<>();
    
    @SuppressWarnings(“未选中”)
    public static final List EMPTY_List=new EmptyList();
    
    在实际代码中,构造函数没有参数

    您的反编译代码:

    public static final List EMPTY_LIST = new Collections.EmptyList(null);
    
    public static final <T> List<T> emptyList() {
        return EMPTY_LIST;
    }
    
    public静态最终列表emptyList(){
    返回空的_列表;
    }
    
    实际代码:

    @SuppressWarnings("unchecked")
    public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    }
    
    @SuppressWarnings(“未选中”)
    公共静态最终列表emptyList(){
    返回(列表)空_列表;
    }
    
    那么,至于类型
    T
    如何变成
    E
    ?通过欺骗
    EMPTY_LIST
    是一种原始类型,它们显式地将其强制转换为
    LIST
    ,并在创建原始
    EMPTY_LIST
    和此显式转换时抑制警告

    实际上,这是非常安全的,因为列表是空的,并且将保持为空

    这个故事的寓意是:不要相信反编译器,尤其是在泛型方面,因为对于类型擦除,反编译器很难知道原始源代码中实际发生了什么。如果您想查看各种开源Java项目(包括OpenJDK)的源代码,请使用有用的(尽管速度较慢)。

    您的反编译代码:

    public static final List EMPTY_LIST = new Collections.EmptyList(null);
    
    public static final <T> List<T> emptyList() {
        return EMPTY_LIST;
    }
    
    实际代码

    @SuppressWarnings("unchecked")
    public static final List EMPTY_LIST = new EmptyList<>();
    
    @SuppressWarnings(“未选中”)
    public static final List EMPTY_List=new EmptyList();
    
    在实际代码中,构造函数没有参数

    您的反编译代码:

    public static final List EMPTY_LIST = new Collections.EmptyList(null);
    
    public static final <T> List<T> emptyList() {
        return EMPTY_LIST;
    }
    
    public静态最终列表emptyList(){
    返回空的_列表;
    }
    
    实际代码:

    @SuppressWarnings("unchecked")
    public static final <T> List<T> emptyList() {
        return (List<T>) EMPTY_LIST;
    }
    
    @SuppressWarnings(“未选中”)
    公共静态最终列表emptyList(){
    返回(列表)空_列表;
    }
    
    那么,至于类型
    T
    如何变成
    E
    ?通过欺骗
    EMPTY_LIST
    是一种原始类型,它们显式地将其强制转换为
    LIST
    ,并在创建原始
    EMPTY_LIST
    和此显式转换时抑制警告

    实际上,这是非常安全的,因为列表是空的,并且将保持为空


    这个故事的寓意是:不要相信反编译器,尤其是在泛型方面,因为对于类型擦除,反编译器很难知道原始源代码中实际发生了什么。如果您想查看各种开源Java项目(包括OpenJDK)的源代码,请使用有用的(尽管速度较慢)。

    除了@MarkoTopolnik answer之外,我可以解释为什么反编译器显示
    null
    被传递到构造函数参数中

    当您创建没有显式构造函数的私有类时,字节码中会生成默认的no arg构造函数作为private:

    private static class EmptyList<E> {
        private EmptyList() {
        }
        ...
    }
    
    从JVM的角度来看,没有“嵌套类”这样的东西。
    EmptyList
    类只是另一个类(名为
    Collections$Emp