什么情况下不能使用 Java 泛型
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 获取更多资讯
什么情况下不能使用 Java 泛型的更多相关文章
- Java泛型数组
文章来自http://blog.csdn.net/orzlzro/article/details/7017435 Java 不支持泛型数组.也就是说, List<String>[] ls ...
- Java 泛型数组
Java 不支持泛型数组.也就是说, List<String>[] ls = new ArrayList<String>[10]; 是不支持的,而 List<String ...
- 笔记-java泛型详解
首先,先说明一下,java泛型文章的出处:http://www.cnblogs.com/lzq198754/p/5780426.html 作为学习笔记保存. 1.为什么需要泛型 泛型在Java中有很重 ...
- 转:java泛型
1.为什么需要泛型 转载请注明出处:http://blog.csdn.net/seu_calvin/article/details/52230032 泛型在Java中有很重要的地位,网上很多文章罗列各 ...
- Java基础11:Java泛型详解
本文对java的泛型的概念和使用做了详尽的介绍. 本文参考https://blog.csdn.net/s10461/article/details/53941091 具体代码在我的GitHub中可以找 ...
- java 泛型详解-绝对是对泛型方法讲解最详细的,没有之一
对java的泛型特性的了解仅限于表面的浅浅一层,直到在学习设计模式时发现有不了解的用法,才想起详细的记录一下. 本文参考java 泛型详解.Java中的泛型方法. java泛型详解 1. 概述 泛型在 ...
- Java技术----Java泛型详解
1.为什么需要泛型 泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇将立足于代码介绍.总结了关于泛型的知识.希望能给你带来一些帮助. 先看下面的代码: List list = ...
- java 泛型详解-绝对是对泛型方法讲解
Reference: http://blog.csdn.net/s10461/article/details/53941091 1. 概述 泛型在java中有很重要的地位,在面向对象编程及各种设计模 ...
- Java泛型三:Java泛型详解
原文地址https://www.cnblogs.com/lzq198754/p/5780426.html 1.为什么需要泛型 泛型在Java中有很重要的地位,网上很多文章罗列各种理论,不便于理解,本篇 ...
随机推荐
- CTF中的命令执行绕过
本位原创作者:Smity 在介绍命令注入之前,有一点需要注意:命令注入与远程代码执行不同.他们的区别在于,远程代码执行实际上是调用服务器网站代码进行执行,而命令注入则是调用操作系统命令进行执行. 作为 ...
- Equalizing by Division
The only difference between easy and hard versions is the number of elements in the array. You are g ...
- Python 【面试强化宝典】
四大数据类型的常用方法 列表常用方法 #1. append 用于在列表末尾追加新的对象 a = [1,2,3] a.append(4) #the result : [1, 2, 3, 4] #2. c ...
- MySQL之慢日志记录、分页
1.慢日志记录 slow_query_log = OFF #是否开启慢日志记录 long_query_time = 2 #时间限制,超过此时间,则记录 slow_query_log_file = C: ...
- 使用sqlmap结合dnslog快速注入
0x01 起因 实际项目中遇到一个oracle延时注入,需要获取数据,几十个库几百张表,等找到关键数据不知道要到哪天. 测试支持带外请求 于是想用使用sqlmap利用DNS进行OOB注入 0x02 阿 ...
- vue.js click点击事件获取当前元素对象
Vue.js可以传递$event对象 <body id="app"> <ul> <li v-on:click="say('hello!', ...
- [Qt] QProcess::startDetached() 避免弹窗,或者窗口一闪而过
主动宣告setProcessState(QProcess::NotRunning) 或者在堆上new一个QProcess. 出处: https://stackoverflow.com/q ...
- java中functional interface的分类和使用
目录 简介 Functional Interface Function:一个参数一个返回值 BiFunction:接收两个参数,一个返回值 Supplier:无参的Function Consumer: ...
- Linux网络服务第七章DNS域名解析服务
端口:53 一.DNS服务器 正向解析:根据域名查IP地址,即将指定的域名解析为相对应的IP地址.域名的正向解析是DNS服务器最基本的功能,也是最常用的功能. 反向解析:根据IP地址查域名,即将指定的 ...
- Python语言类型
Python是一门动态解释型的强类型语言. 对这句话进行解析,语言分为动态的和静态的,编译型和解释型的,强类型的和弱类型的语言之分. 下面对三种不同维度的类型的语言进行解释: 1.编译型和解释型 差别 ...