前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >泛型类的正确用法

泛型类的正确用法

作者头像
FunTester
发布2020-10-29 10:26:17
8540
发布2020-10-29 10:26:17
举报
文章被收录于专栏:FunTester

在准备下次直播Java基础的内容中,偶然看到Java泛型这个知识点,突然有了点想法,之前一直纠结的一个问题有了解答的思路。

问题:我在多线程任务基类中定义了一个泛型T的对象t,但是一直没有找到一个特别合适的发光点,感觉跟重新写一个内部类差别不大,偶尔在匿名类中使用,非但没有更加灵活,反而衍生出一些其他多线程锁的问题。

具体代码如下:

完整的代码地址:「https://github.com/JunManYuanLong/FunTester」

代码语言:javascript
复制

public abstract class ThreadBase<T> extends SourceCode implements Runnable {

····省略代码···
    /**
     * 用于设置访问资源,用于闭包中无法访问包外实例对象的情况
     * @since 2020年10月19日,统一用来设置HTTPrequestbase对象.同样可以用于执行SQL和redis查询语句或者对象,暂未使用dubbo尝试
     */
    public T t;

这个t对象在之前唯一用到的地方就是在标记执行任务的时候用到,把生成的标记(通常是String类型)赋值到t中,然后在接下来的过程中访问。但是也仅仅是多了一个存储的地方,实际上标记对象的方法会把标记返回。

突然想到的解决之道是,在除去几种基本类型的多线程任务类(多位abstract类)属性意外,针对需要引入新的属性的实践任务类,例如RequestThreadTimeUpdateSqlThread等多线程任务类中,额外的属性对象就可以用这个泛型T代替。

突觉自己以前走了很多弯路,对泛型的掌握和应用太浅薄,说干就干了,马上对现有的性能测试框架中的abstract类和实现类都改一遍。

这里取RequestThreadTimes为例分享一下代码,有兴趣的同学可以在GitHub上看到我的提交记录,对比一下前后的修改。

代码语言:javascript
复制
package com.fun.frame.thead;

import com.fun.base.constaint.ThreadLimitTimesCount;
import com.fun.base.interfaces.MarkThread;
import com.fun.frame.httpclient.FanLibrary;
import com.fun.frame.httpclient.FunRequest;
import com.fun.frame.httpclient.GCThread;
import org.apache.http.client.methods.HttpRequestBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * http请求多线程类
 */
public class RequestThreadTimes<T extends HttpRequestBase> extends ThreadLimitTimesCount<HttpRequestBase> {

    static Logger logger = LoggerFactory.getLogger(RequestThreadTimes.class);

    /**
     * 单请求多线程多次任务构造方法
     *
     * @param request 被执行的请求
     * @param times   每个线程运行的次数
     */
    public RequestThreadTimes(HttpRequestBase request, int times) {
        super(request, times, null);
    }

    /**
     * 应对对每个请求进行标记的情况
     *
     * @param request
     * @param times
     * @param mark
     */
    public RequestThreadTimes(HttpRequestBase request, int times, MarkThread mark) {
        super(request, times, mark);
    }

    protected RequestThreadTimes() {
        super();
    }

    @Override
    public void before() {
        super.before();
        GCThread.starts();
    }

    /**
     * @throws Exception
     */
    @Override
    protected void doing() throws Exception {
        FanLibrary.executeSimlple(t);
    }

    @Override
    public RequestThreadTimes clone() {
        RequestThreadTimes threadTimes = new RequestThreadTimes();
        threadTimes.times = this.times;
        threadTimes.t = FunRequest.cloneRequest(t);
        threadTimes.mark = mark == null ? null : mark.clone();
        return threadTimes;
    }


}

关于类名那一行,我尝试了很多中办法,包括public class RequestThreadTimes<T extends HttpRequestBase> extends ThreadLimitTimesCount<HttpRequestBase> {public class RequestThreadTimes<T> extends ThreadLimitTimesCount<HttpRequestBase> {public class RequestThreadTimes extends ThreadLimitTimesCount<HttpRequestBase> {public class RequestThreadTimes<HttpRequestBase> extends ThreadLimitTimesCount<HttpRequestBase> {,然后报出了各种错误,最终我选择了第一种写法,据我粗浅的尝试,被继承的父类中T可以声明成为HttpRequestBase类,然后在代码中关于父类的操作,如super(request, times, mark);中是可以成立的,然后在本类名后面的泛型不能声明对象,只能用<T extends HttpRequestBase>限制创建对象是声明泛型的上限。

这里还涉及到一个标记方法中类型转化的修改,如下:

代码语言:javascript
复制
    @Override
    public String mark(ThreadBase threadBase) {
        if (threadBase instanceof RequestThreadTime) {
            RequestThreadTime<HttpRequestBase> req = (RequestThreadTime<HttpRequestBase>) threadBase;
            return mark(req.t);
        } else if (threadBase instanceof RequestThreadTimes) {
            RequestThreadTimes<HttpRequestBase> req = (RequestThreadTimes<HttpRequestBase>) threadBase;
            return mark(req.t);
        } else {
            ParamException.fail(threadBase.getClass().toString());
        }
        return EMPTY;
    }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FunTester 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档