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. 如何将SqlServer配置为django的数据源(2.2以后版本)

    django-pyodbc-azure 是一个官方推荐的 第三方django数据库支持backend. 根据官网的介绍django-pyodbc-azure 只能支持到 django 2.1.如果涉及 ...

  2. Youtube推荐算法的前世今生

    第一阶段,基于User-Video图游历算法,2008年[1]. 在这个阶段,YouTube认为应该给用户推荐曾经观看过视频的同类视频,或者说拥有同一标签的视频.然而此时,YouTube的视频已是数千 ...

  3. Mysql链接查询

    连接查询--交叉连接将两张表的数据与另外一张表彼此交叉原理:1. 从第一张表一次取出每一条记录2. 取出每一条记录之后,与另外一张表的全部记录挨个匹配3. 没有任何匹配条件,所有的结果都会进行保留4. ...

  4. tensorflow1.0 数据队列FIFOQueue的使用

    import tensorflow as tf #模拟一下同步先处理数据,然后才能取数据训练 #tensorflow当中,运行操作有依赖性 #1.首先定义队列 Q = tf.FIFOQueue(3,t ...

  5. 高德局部刷新标记点,bug解决

    将接口返回的经纬集合点在高德地图上标记展示, 如果实时刷新地图标记点,不加优化,则会造成过多的带宽消耗 所以,地图只需加载一次,局部更新标记点就好了 代码: <template> < ...

  6. 通过纯css实现图片居中的多种实现方式

    html结构: <div class="demo" style="width: 800px;height: 600px; border:1px solid #ddd ...

  7. 20199308《Linux内核原理与分析》第十一周作业

    缓冲区溢出漏洞实验 实验步骤 一.初始设置 1.Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难, ...

  8. wireshark的基础认识

    简单的抓包分析 使用过滤功能: 数据分别经过:物理层-> 数据链路层->网络层 ->传输层 ->应用层 下面将详细的查分各个层所涉及的东西. 物理层:单位是比特流 数据链路层; ...

  9. NFS共享设置

    一.安装所需要的软件环境[root@fengling ~]# yum -y install rpcbind nfs-utils二.创建共享目录mkdir /web三.启动服务[root@fenglin ...

  10. HDU 6341 Let Sudoku Rotate

    #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #defi ...