1. 前言

Java 1.5 引入了泛型来保证类型安全,防止在运行时发生类型转换异常,让类型参数化,提高了代码的可读性和重用率。但是有些情况下泛型也是不允许使用的,今天就总结一下编码中不能使用泛型的一些场景。

2. 基本类型无法直接使用泛型

以下写法是错误的:

// error
Map<int,char> wrong= new HashMap<>()

基本类型是不能够作为泛型类型的,需要使用它们对应的包装类。

// OK
Map<Integer,Character> wrong= new HashMap<>()

3. 泛型类型无法被直接实例化

泛型类型可以理解为一个抽象类型,只是代表了类型的抽象,因此我们不能直接实例化它,下面的做法也是错误的:

 public <E> E first(List<E> list){
// error
E e = new E();
return list.get(0);
}

4. 泛型无法作为静态变量类型

Java 中的静态类型随着类加载而实例化,此时泛型的具体类型并没有声明。同时因为静态变量作为所有对象的共享变量,只有类实例化或者方法调用时才能确定其类型。如果是泛型类型将无法确定其类型。同样在类上声明的泛型也无法作为返回值类型出现在类的静态方法中,下面的写法也是错误的:

public class Generic<T>{
// 不能将类声明的泛型类型作为静态变量
public static T t;
// 也不能将类声明的泛型类型作为 静态方法的返回值
public static T rtval(List<T> list){
return list.get(0);
}
}

5. 无法进行 instanceof 判断

Java 中的泛型是伪泛型,在编译期会被擦除,运行的字节码中不存在泛型,所以下面的判断条件无法进行:

public static <E> void wrong(List<E> list) {
// error
if (list instanceof ArrayList<Integer>) {
}
}

但是泛型的无界通配符 <?> 可以进行 instanceof 判断,你仔细想想为什么。

6. 无法创建参数化类型的数组

首先下面这种写法是对的:

// OK
List[] arrayOfLists = new List[2];

但是加上了泛型就编译不通过了:

//error
List<Integer>[] arrayOfLists = new List<Integer>[2];

如果不这么规定将引发以下逻辑错误:

// 如果上面的成立,则下面的也应该成立
Object[] stringLists = new List<String>[];
// 那么我们可以放入 字符串 List
stringLists[0] = new ArrayList<String>();
// 放入 Integer list
stringLists[1] = new ArrayList<Integer>();
// 这显然不合理

7. 不能直接或者间接扩展Throwable

下面的两种写法将引发编译错误:

//  不能间接地扩展 Throwable
class IndirectException<T> extends Exception {} // 不能直接地扩展 Throwable
class DirectException<T> extends Throwable {}

如果成立将出现:

 try {
// ...
} catch (T e) {
// 类型不确定 无法处理具体的异常逻辑
}

你如何才能对异常进行具体的处理,这显然不便于精确的异常处理逻辑。但是你可以抛出一个 不确定的异常,但是同样不能在静态方法中使用类声明的泛型:

class Parser<T extends Exception> {
// 这样是对的
public void okThrow(File file) throws T {
// ...
}
// 静态方法不能出现类声明的泛型类型作为返回值和异常
public static void wrongThrow(File file) throws T {
}
}

8. 泛型擦除后相同参数签名的方法不能重载

由于泛型擦除的原因,以下的不视为方法的重载且无法编译 :

public class NoReload {
public void sets(Set<String> strSet) { }
public void sets(Set<Integer> intSet) { }
}

9. 总结

今天总结了 Java 泛型的一些使用误区,虽然平常 IDE 的提示会告诉我们,但是这也是我们经常会忽略的一些知识点。如果有不足之处,请留言指正。如果你想对泛型了解更多,可关注公众号:码农小胖哥 回复 generic 获取相关的学习笔记。

关注公众号:Felordcn 获取更多资讯

个人博客:https://felord.cn

什么情况下不能使用 Java 泛型的更多相关文章

  1. Java泛型数组

    文章来自http://blog.csdn.net/orzlzro/article/details/7017435 Java 不支持泛型数组.也就是说, List<String>[] ls ...

  2. Java 泛型数组

    Java 不支持泛型数组.也就是说, List<String>[] ls = new ArrayList<String>[10]; 是不支持的,而 List<String ...

  3. 笔记-java泛型详解

    首先,先说明一下,java泛型文章的出处:http://www.cnblogs.com/lzq198754/p/5780426.html 作为学习笔记保存. 1.为什么需要泛型 泛型在Java中有很重 ...

  4. 转:java泛型

    1.为什么需要泛型 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52230032 泛型在Java中有很重要的地位,网上很多文章罗列各 ...

  5. Java基础11:Java泛型详解

    本文对java的泛型的概念和使用做了详尽的介绍. 本文参考https://blog.csdn.net/s10461/article/details/53941091 具体代码在我的GitHub中可以找 ...

  6. java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一

    对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在 ...

  7. Java技术----Java泛型详解

    1.为什么需要泛型 泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇将立足于代码介绍.总结了关于泛型的知识.希望能给你带来一些帮助. 先看下面的代码: List list = ...

  8. java 泛型详解-绝对是对泛型方法讲解

    Reference:  http://blog.csdn.net/s10461/article/details/53941091 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模 ...

  9. Java泛型三:Java泛型详解

    原文地址https://www.cnblogs.com/lzq198754/p/5780426.html 1.为什么需要泛型 泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇 ...

随机推荐

  1. 15分钟从零开始搭建支持10w+用户的生产环境(二)

    上一篇文章,把这个架构的起因,和操作系统的选择进行了详细说明. 原文地址:15分钟从零开始搭建支持10w+用户的生产环境(一)   二.数据库的选择 对于一个10W+用户的系统,数据库选择很重要. 一 ...

  2. 单图像三维重建、2D到3D风格迁移和3D DeepDream

    作者:Longway Date:2020-04-25 来源:单图像三维重建.2D到3D风格迁移和3D DeepDream 项目网址:http://hiroharu-kato.com/projects_ ...

  3. 大数据Hbase相关运维题

    1.启动先电大数据平台的 Hbase 数据库,其中要求使用 master 节点的RegionServer.在 Linux Shell 中启动 Hbase shell,查看 HBase 的版本信息.(相 ...

  4. C#线程学习笔记

    本笔记摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/18/Thread.html,记录一下学习,方便后面资料查找 一.线程的介绍 进程(Proce ...

  5. 一图了解redis

    了解redis,这一张图就够了,话不多说,看图: 版权所有,转载请注明出处,欢迎讨论交流

  6. vue显示富文本

    来源:https://segmentfault.com/q/1010000013952512 用  v-html 属性解决

  7. Kubernetes产生背景、核心概念

    Kubernetes是什么 • Kubernetes是Google在2014年开源的一个容器集群管理系统,Kubernetes简称K8S. • Kubernetes用于容器化应用程序的部署,扩展和管理 ...

  8. Oracle把表记录恢复到指定时间节点

    可以执行以下命令alter table 表名 enable row movement; --开启表行移动flashback table 表名 to timestamp to_timestamp('20 ...

  9. Handler 机制(一)—— Handler的实现流程

    由于Android采用的是单线程模式,开发者无法在子线程中更新 UI,所以系统给我提供了 Handler 这个类来实现 UI 更新问题.本贴主要说明 Handler 的工作流程. 1. Handler ...

  10. WMware中Ubuntu系统安装VMware tools

    在VMware的虚拟机中安装完ubuntu之后,继续安装VMware tools. 一般情况下,这时都有光驱的图标,点开就能找到"VMwareTools-10.0.10-4301679.ta ...