惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
腾讯CDC
T
Threatpost
L
Lohrmann on Cybersecurity
P
Proofpoint News Feed
The Cloudflare Blog
博客园 - 聂微东
MyScale Blog
MyScale Blog
M
MIT News - Artificial intelligence
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Project Zero
Project Zero
Simon Willison's Weblog
Simon Willison's Weblog
S
Schneier on Security
Spread Privacy
Spread Privacy
The GitHub Blog
The GitHub Blog
D
DataBreaches.Net
S
Securelist
Schneier on Security
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Cisco Talos Blog
Cisco Talos Blog
博客园 - 叶小钗
量子位
I
InfoQ
J
Java Code Geeks
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
人人都是产品经理
人人都是产品经理
博客园_首页
C
CERT Recently Published Vulnerability Notes
I
Intezer
Y
Y Combinator Blog
T
Tailwind CSS Blog
Microsoft Security Blog
Microsoft Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
A
About on SuperTechFans
A
Arctic Wolf
阮一峰的网络日志
阮一峰的网络日志
P
Proofpoint News Feed
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Vercel News
Vercel News
PCI Perspectives
PCI Perspectives
The Last Watchdog
The Last Watchdog
月光博客
月光博客

博客园 - 欢乐豆123

软件设计师考试 - 有限自动机 软件设计师考试 - 排序算法 哈夫曼树以及哈夫曼编码 软件设计师案例题型 - DFD(数据流图) 软件设计师考试 - 二分查找 软件设计师考试 - Gantt图与PERT图(项目管理) 软件设计师考试 - 数据表示(原码、反码、补码、移码) 软件设计师考试 - 上午题型分析 软件设计师考试 - 下午题型分析 软件设计师考试-应用技术 内存溢出问题 常见的算法类型 排序算法的介绍 微信生态梳理 海明码介绍 Elasticsearch 实战:基于 function_score 的搜索与权重排序 Nexus的简单介绍以及如何上传自定义包 设计模式-桥接模式(Bridge Pattern) 设计模式简介 jmeter压测 sdkman-管理多个版本的JDK SpringBoot中使用Aop统一拦截MQ消息处理 项目管理流程以及规范
Java-泛型的使用
欢乐豆123 · 2025-04-21 · via 博客园 - 欢乐豆123

Java-泛型的使用

    在日常开发中,我们经常会遇到一种情况:为了通用性,不得不写很多重复代码。Java 泛型(Generic)就是为了解决这个问题而诞生的。本文将通过实际项目中的 UserHolder 优化过程,带你一步步理解并学会使用泛型。

   一、Java 泛型介绍

   泛型是一种代码参数化的机制,它允许类、接口、方法在声明时使用类型参数,从而提高代码的复用性、类型安全性和可读性。

List<String> list = new ArrayList<>();

   这里 List<String> 就是使用了泛型,限定了这个列表只能存储 String 类型的数据,编译器会自动进行类型检查。

   泛型最常见的用途是集合类(如 List<T>、Map<K, V>),但它不仅仅局限于此,还可以用于我们自己的类和方法中。

   二、项目实践

   1. 应用举例

   在我们的应用中,常常使用 ThreadLocal 保存当前请求线程的用户信息,例如:

public class UserHolder {

    /**
     * C端用户上下文
     */
    private static final ThreadLocal<UserContext> threadLocal = new ThreadLocal<>();

    /**
     * 管理端用户上下文
     */
    private static final ThreadLocal<AdminUserContext> adminThreadLocal = new ThreadLocal<>();

    public static UserContext get() {
        return threadLocal.get();
    }

    public static void set(UserContext context) {
        threadLocal.set(context);
    }

    public static void clear() {
        threadLocal.remove();
    }
    public static AdminUserContext getAdmin() {
        return adminThreadLocal.get();
    }
    public static void setAdmin(AdminUserContext context) {
        adminThreadLocal.set(context);
    }

    public static void clearAdmin() {
        adminThreadLocal.remove();
    }
}

     在这个 UserHolder 类中,hreadLocal 和 adminThreadLocal 用于分别存放C端用户上下文和管理端用户上下文,它们通过 ThreadLocal 提供线程隔离,确保每个线程能够独立存储和访问自己的用户信息。

     2.  问题分析

     1)代码重复

   上面代码中,threadLocal 和 adminThreadLocal 的功能完全相似,唯一的区别是存储的用户上下文不同。这种重复的代码会导致维护上的麻烦,一旦需要对存取逻辑进行修改,可能需要修改多个地方,增加了出错的风险。

     2)不便于扩展

     随着业务的扩展,可能会增加更多的用户类型(例如,律师端用户、财务端用户等),每添加一个新的用户类型,就需要新增一个 ThreadLocal 变量以及相应的 getter、setter 方法,这会导致代码变得越来越冗长且不易扩展。

     3. 使用泛型优化UserHolder

     我们可以通过泛型的方式来简化 UserHolder 类,减少重复代码,使其更加灵活、可扩展。我们将 ThreadLocal 的类型化抽象出来,利用泛型让同一个 ThreadLocal 类可以存储不同类型的用户上下文,从而实现统一管理。

     优化后的 UserHolder 代码如下:

public class UserHolder<T> {
    // 泛型化的ThreadLocal,用于存储不同类型的上下文
    private static final ThreadLocal<Object> threadLocal = new ThreadLocal<>();

    public static <T> T get(Class<T> clazz) {
        return clazz.cast(threadLocal.get());
    }

    public static <T> void set(T context) {
        threadLocal.set(context);
    }

    public static void clear() {
        threadLocal.remove();
    }
}

    在优化后的 UserHolder 中,我们利用了泛型,get 和 set 方法都变得更加通用,可以接受任意类型的上下文对象。

    使用时,我们可以根据具体的上下文类型进行操作,例如:

// 设置C端用户上下文
UserHolder.set(new UserContext());

// 获取C端用户上下文
UserContext userContext = UserHolder.get(UserContext.class);

// 设置管理端用户上下文
UserHolder.set(new AdminUserContext());

// 获取管理端用户上下文
AdminUserContext adminUserContext = UserHolder.get(AdminUserContext.class);

    通过这种方式,UserHolder 类的代码更加简洁且具有可扩展性,当需要增加新的用户类型时,只需要在 set 和 get 方法中指定相应的类型即可,不再需要为每个类型定义一个独立的 ThreadLocal 变量。

    三、总结

   上文中,我们以UserHolder 中的 ThreadLocal 优化为例,演示了如何使用泛型提高代码的简洁性、可扩展性和维护性。通过泛型的方式,我们不仅解决了原始代码中的重复问题,还使得 UserHolder 能够灵活地存储和访问不同类型的用户上下文。

   使用泛型优化后的代码更加简洁,且容易扩展。当业务需求发生变化时,我们只需要修改少量代码,新增用户类型变得更加容易,减少了重复代码和维护成本。