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. BUG 测试计划

       性能追求 目前状况 测试标准 APP平稳运行,无crush现象   快速下拉翻页时,崩溃退出     要求多人使用,均流畅无异常退出方可               页面的放大缩小不会造成页面显 ...

  2. stand up meeting 12/3/2015

    part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 初始化弹窗的弹出位置并捕捉弹窗区域内的鼠标控制事件,初步解决弹窗的拖拽功能:    6 UWP对控件的支持各种看不懂,属性 ...

  3. Java 多线程--ThreadLocal Timer ExecutorService

    ThreadLocal /** * ThreadLocal:每个线程自身的存储本地.局部区域 * @author xzlf * */ public class ThreadLocalTest01 { ...

  4. Content-Type 四种常见的 POST 提交数据方式

    参考于: https://blog.csdn.net/tycoon1988/article/details/40080691(了解) 和: https://www.gy0929.com/wz/1420 ...

  5. 如何在 Inno Setup 中执行命令行的命令

    Pascal Scripting: Exec Prototype: function Exec(const Filename, Params, WorkingDir: String; const Sh ...

  6. Ubuntu忘记超级用户root密码,重新设置密码 转载

    原文链接:https://blog.csdn.net/weixin_37909391/article/details/80691601 Ubuntu版本:Ubuntu 16.04.3 LTS 1启动系 ...

  7. 理解分布式一致性:Raft协议

    理解分布式一致性:Raft协议 什么是分布式一致性 Leader选举 日志复制流程 term选举周期 timeout 选举和选举timeout 选举分裂 日志复制和心跳timeout 在分布式系统中, ...

  8. 谷歌提高Google Assistant中Voice Match的准确性

    谷歌正在提高 Google Assistant 中 Voice Match 的准确性,使其变得更加完善.谷歌表示一旦用户在 Google Assistant 中启用 Voice Match 功能,那么 ...

  9. 【JAVA基础】10 Object类

    1. Object类概述 是类层次结构的根类 每个类都使用 Object 作为超类 所有类都直接或者间接的继承自该类 所有对象(包括数组)都实现这个类的方法. 2. Object的构造方法 publi ...

  10. 【Linux常见问题】CentOS 6 root用户密码忘记,找回密码方法

    1.Linux的root密码修改不像Windows的密码修改找回,Windows的登录密码忘记需要介入工具进行解决.CentOS6和CentOS7的密码方法也是不一样的,具体如下: 2.centos ...