不能初始化泛型参数和数组

简介:

泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码: 

复制代码
class Foo<T>{
    //private T t =new T();//报错Cannot instantiate the type T
    //private T[] tArray= new T[5];//报错Cannot create a generic array of T
    private List<T> list= new ArrayList<T>();
}
复制代码

这段代码有什么问题?

t,tArray,list都是类变量,都是通过new声明了一个类型,看起来非常的相似.

但是这段代码是通不过的,因为编译期在编译时需要获得T类型,但是泛型在编译期类型已经被擦除了,所以new T()和new T[5] 都会报错,

但是你也许会认为,泛型类型可以擦除为顶级的Object类,那T类型擦除成Object不就可以编译了?

这样也不行,泛型只是Java语言的一部分,Java语言毕竟是一种强类型,编译型的安全语言,要确保运行期的稳定性和安全性就必须要求在编译器上严格检查.

但是为什么new ArrayList<T>()却不会报错呢?

这是因为ArrayList表面上是泛型,其实已经在编译期转型为了Object类型了,要看一下ArrayList的源代码就清楚了.

复制代码
 1 public class ArrayList<E> extends AbstractList<E>
 2         implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
 3     /**
 4      * The array buffer into which the elements of the ArrayList are stored.
 5      * The capacity of the ArrayList is the length of this array buffer.
 6      */
 7     private transient Object[] elementData;
 8     /**
 9      * Constructs an empty list with an initial capacity of ten.
10      */
11     public ArrayList() {
12         this(10);
13     }    
14         
15     /**
16      * Returns the element at the specified position in this list.
17      *
18      * @param  index index of the element to return
19      * @return the element at the specified position in this list
20      * @throws IndexOutOfBoundsException {@inheritDoc}
21      */
22     public E get(int index) {
23         rangeCheck(index);
24 
25         return elementData(index);
26     }
27     E elementData(int index) {
28         return (E) elementData[index];
29     }        
30 }
复制代码

 

 注意看elementData定义,它容纳了ArrayList的所有元素,其类型是Object数组,因为Object是所有类的父类,数组又允许协变(Covariant),因此elementData数组可以容纳所有的实例对象.

元素加入时向上转型为Object类型(E类型转变为Object),取出时向下转型为E类型(Object转为E类型).

在某些情况下,我们确实需要泛型数组,怎么处理?

复制代码
 1 import java.lang.reflect.Array;
 2 import java.util.ArrayList;
 3 import java.util.List;
 4 
 5 public class Client {
 6     public static void main(String[] args) {
 7         
 8         
 9     }
10 }
11 
12 class Foo<T>{
13     //不再初始化,由构造函数初始化
14     private T t;
15     private T[] tArray;
16     private List<T> list= new ArrayList<T>();
17     //构造函数初始化
18     public Foo(){
19         try {
20             Class<?> tType = Class.forName("");
21             t = (T)tType.newInstance();
22             tArray = (T[])Array.newInstance(tType,5);
23         } catch (Exception e) {
24             e.printStackTrace();
25         }
26     
27     }
28 }
复制代码

 

此时运行就没有任何问题了,剩下的问题就是怎么在运行期获得T的类型.也就是tType参数.一般情况下泛型类型是无法获取的,不过在客户端调用时多传输一个T类型的class就会解决问题.

类的成员变量是在类初始化前初始化的,所以要求在初始化前它必须具有明确的类型.否则就只能声明,不能初始化.

 


本文转自SummerChill博客园博客,原文链接:http://www.cnblogs.com/DreamDrive/p/5624165.html,如需转载请自行联系原作者
相关文章
|
18天前
|
人工智能 JSON API
全网刷屏的 Jev 模型正式开放!一手实战测评 + 保姆级教程
全网爆火的 Jev 模型是什么?有什么用?怎么使用?怎么接入 AI 编程工具?效果真的好么?傻子可懂的 Jev 保姆级实战教程 + 项目实战测评来啦
8679 25
|
17天前
|
人工智能 并行计算 PyTorch
秋叶 ComfyUI 2026 整合包 v3.2 完整部署教程:Python 3.13 + Torch 2.13 全栈升级
秋叶aaaki ComfyUI 2026年8月整合包v3.2正式发布!全面升级Python 3.13.11、PyTorch 2.13.0+cu130及ComfyUI v0.30.2,原生支持MiniMax H3、Wan 2.2、Qwen-Image-2.1等2026主流音视频/图像模型,解压即用,无需环境配置。
3201 14
|
17天前
|
人工智能 测试技术 API
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
Jev是TypeSafe AI推出的“系统一模型”,不生成文本,专做毫秒级结构化决策:Choice(多选)、Score(打分)、Noul(是非概率)。响应快193倍、成本低444倍,适合工单路由、内容审核、测试定级等高频判断场景。
2136 4
最近全网爆火的 Jev 到底是什么?适合干什么、怎么用,一篇讲透!
|
6天前
|
人工智能 JSON Linux
【全网最详细】ComfyUI使用教程:下载+本地部署+配置+工作流搭建一篇搞定(2026最新版)
ComfyUI是一款免费开源的本地AI绘图工具,采用节点式工作流设计,支持文生图、图生图、局部重绘、放大、换脸等多种功能。可离线运行,依赖显卡加速,无需联网。支持自定义流程保存与分享,插件生态丰富,适合进阶用户。(239字)
|
17天前
|
云安全 人工智能 安全
|
11天前
|
人工智能 Linux 开发者
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
Codex是OpenAI推出的AI编程智能体,可读取本地项目、理解需求并自动修改代码。支持桌面GUI、命令行(CLI)及VS Code/Cursor插件三种形态,覆盖可视化操作、终端高效开发与编辑器无缝集成场景,助开发者用自然语言驱动编码全流程。(239字)
【2026国内使用】Codex安装过程一篇讲透(Win/Mac/Linux全支持)
|
11天前
|
人工智能 JSON 编解码
【2026最新版】ComfyUI本地部署教程,新手也能看懂!
ComfyUI是本地运行的AI绘画工具,采用节点式工作流设计:通过拖拽连接“加载模型”“提示词编码”“采样”“解码”等模块,实现高度可控的文生图。新手推荐使用秋叶整合包,一键启动、内置模型管理与插件安装器,轻松上手。(239字)