什么情况下不能使用java泛型

码农小胖哥      2022-05-04     174

关键词:

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

为什么公司新来的阿里p8大佬说:这几种情况下不能使用java泛型

最新互联网大厂面试真题、Java程序员面试策略(面试前的准备、面试中的技巧)请访问GitHub1.前言Java1.5引入了泛型来保证类型安全,防止在运行时发生类型转换异常,让类型参数化,提高了代码的可读性和重用率。但是有些情... 查看详情

java示例代码_在没有警告的情况下,对泛型类型使用泛型工厂

java示例代码_在没有警告的情况下,对泛型类型使用泛型工厂 查看详情

什么情况下用到@superesswarning

参考技术A当你的java代码后面有警告时,可以分别使用相对应值来解决@SuppressWarnings(“deprection”);用途:使用了不赞成的类或者方法时使用@SuppressWarnings(“unchecked”);用途:使用了未检查时的转换时的警告,例如当使用泛型没有... 查看详情

Java 泛型与 C++ 模板有何不同?为啥我不能使用 int 作为参数?

...lates?Whycan\'tIuseintasaparameter?Java泛型与C++模板有何不同?为什么我不能使用int作为参数?【发布时间】:2009-06-1513:32:13【问题描述】:我正在尝试创建ArrayList<int>myList=newArray 查看详情

在没有泛型类约束的情况下,将泛型类型与其默认值进行比较,会产生编译时错误

...是使用默认关键字的好机会。但它没有编译,我想不出为什么。下面的例子说 查看详情

Typescript:在这种情况下如何使用泛型类型键入函数?

】Typescript:在这种情况下如何使用泛型类型键入函数?【英文标题】:Typescript:Howtypeafunctionusinggenerictypeinthiscase?【发布时间】:2020-02-2700:56:20【问题描述】:我有这个类型定义typeFuncType<T>=(value:T)=>T我想使用这种类型实现... 查看详情

java泛型中的下限

谁说明下原理,上限就不用了,已经明白,不明白下限有什么好处楼上到底学没学过泛型?????不知道就别说,我这正郁闷呢这个要比较起来说明的,设置你所谓的上限下限是在参数声明的时候,其他情况不行1首先确定的... 查看详情

java中的泛型类是啥东西?

在JavaSE1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换... 查看详情

java中泛型的使用

...只要了解了泛型的一般使用情况就能够解决多半的问题。什么是泛型?试想一个简单的添加方法(method),如下:long,float或double类型并不能当作输入传给这个方法。如果从该方法中抽象出数据类型,就可以得到一个新的方式,... 查看详情

泛型的使用

...集合中没有使用泛型的情况下 1.没有使用泛型,不论什么Object及其子类的对象都能够加入进来 2.强转时,可能报ClassCastException的异常②.在集合中使用泛型&nb 查看详情

java泛型

这里对java泛型做下小结:  为什么会有泛型?     在不使用泛型时,往集合中添加对象可以添加不同类型的对象,在遍历集合时往往是将集合中的元素以同一类型取出,这时集合中的不是该类型的元素就会发生运... 查看详情

java_泛型笔记(代码片段)

文章目录Java_泛型简介Java_泛型的概念Java_为什么存在泛型Java_自定义泛型结构Java_泛型的声明Java_泛型的实例化Java_泛型类Java_泛型方法Java_泛型在继承上的体现Java_通配符的使用Java_泛型简介集合容器类在设计阶段/声明阶段不能确... 查看详情

为啥我不能在 C# 应用程序中使用泛型类型作为入口点?

...点?【英文标题】:WhyIcannotuseasentrypointinC#appagenerictype?为什么我不能在C#应用程序中使用泛型类型作为入口点?【发布时间】:2015-03-1817:10:15【问题描述】:在C#中,方法Main必须是非泛型类型才能被选为入口点。这是为什么呢?... 查看详情

为啥 Java 枚举文字不能具有泛型类型参数?

...题】:Whyshouldn\'tJavaenumliteralsbeabletohavegenerictypeparameters?为什么Java枚举文字不能具有泛型类型参数?【发布时间】:2010-11-2709:12:04【问题描述】:Java枚举很棒。泛型也是如此。当然,我们都知道后者由于类型擦除的局限性。但是... 查看详情

2022-08-01java之泛型枚举多线程

(目录)一、泛型1.什么是泛型泛型是JavaSE5出现的新特性,泛型的本质是类型参数化或参数化类型,在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型。2.泛型的意义一般的类和方法,只能使用具体... 查看详情

c#在不知道类型的情况下,如何判断并使用带泛型的扩展方法?

业务情景是这样的:已知两个接口::publicinterfaceIApublicinterfaceIB已知三个泛型类:publicclassCa<T>:IApublicclassCb<T>:IBpublicclassCc<T>以及已知一个扩展方法:publicstaticclassXXXExtensionpublicstaticCc<T>CalculateC<T>(thisCa<T>... 查看详情

java泛型

...用泛型的优缺点:优点:避免了类型转换的的麻烦,存储什么类型,取出什么类型;把运行异常,提升到了编译期缺点:只能存储单一类型     泛型就是编写模板代码来适应任意类型不必对类型进行强制转换编... 查看详情

我们如何在不使用泛型类型进行自定义的情况下处理身份核心用户管理和用户存储的多个用户使用情况?

】我们如何在不使用泛型类型进行自定义的情况下处理身份核心用户管理和用户存储的多个用户使用情况?【英文标题】:Howcanwehandlemorethanoneuserusageforidentitycoreusermanagementanduserstorewithoutcustomizationwithgenerictype?【发布时间】:2021-0... 查看详情