天天财汇 购物 网址 万年历 小说 | 三峰软件 小游戏 视频
TxT小说阅读器
↓小说语音阅读,小说下载↓
一键清除系统垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放,产品展示↓
首页 淘股吧 股票涨跌实时统计 涨停板选股 股票入门 股票书籍 股票问答 分时图选股 跌停板选股 K线图选股 成交量选股 [平安银行]
股市论谈 均线选股 趋势线选股 筹码理论 波浪理论 缠论 MACD指标 KDJ指标 BOLL指标 RSI指标 炒股基础知识 炒股故事
商业财经 科技知识 汽车百科 工程技术 自然科学 家居生活 设计艺术 财经视频 游戏--
  天天财汇 -> 科技知识 -> 如何看待“Hutool”工具类库广受欢迎? -> 正文阅读

[科技知识]如何看待“Hutool”工具类库广受欢迎?

[收藏本文] 【下载本文】
不知道从何时开始,很多人开始吹捧Hutool工具类库。我也去码云上看了这个类库,到目前为止star达到惊人的10.4K!那是不是意味着这个类库极其的优…
哈哈,作为Hutool作者回答下这个问题。
1、star惊人的高证明用户群比较多(当然和我宣传方式有关,这个不作为优秀的唯一标准),虽然Hutool并不能称为优秀,但是我们希望它向优秀不断迈进。Hutool拥有清晰的模块,完善规范的注释和详细的中文文档,这个我觉得是它的优势。
Hutool的维护从2013年开始,到现在也有7个年头了,中间的工具方法是用户一点一点参与积累的结果。大而全是工具类的趋势,但是到现在Hutool依旧坚持无依赖(除了个别模块封装第三方库外)
2、个人不认同“总体质量不高”这类说法,不知道这个"质量"如何定义?如果从单元测试覆盖率来讲,确实不高,现在覆盖只有30%左右。
3、工具本身没有任何耦合性,Hutool也是。当然从使用习惯来讲,用户有选择工具的权利,commons系列用惯了确实再改变也比较麻烦(比如我是Eclipse重度用户,至今虽然迁移到IDEA,但是快捷键依旧改不过来)
4、commons系列的突出问题我想你也有了解,比如著名的BeanUtils.copyProperties性能问题,这个我想Hutool还是有优势的。(当然比起cglib肯定差)
最后我想说Hutool工具也不是完全原创,你能在工具中找到很多其它库的影子,包括jodd、Guava、Apache Commons等,Hutool在创新的过程中,还是有大量借鉴和学习的。
奉劝一下戾气太重的各位:人民群众喜闻乐见,哪儿轮到一群妖魔鬼怪指指点点。
有用的技术,解决实际问题就是好技术。没用的技术,再NB也是空中楼阁。
至于说,代码质量什么的,你就输了。毕竟,绝大部分交付类的项目,谈质量就是搞笑。
交付类的项目,要的是低成本,快速开发,时间不等人,成本要控制才有利润。
最好拿ruoyi,改改就能直接上线。甲方一签字验收,拿到项目款,才是生存之道。
这个问题真是槽点满满
1、到目前为止star达到惊人的10.4K!那是不是意味着这个类库极其的优秀,才让广大开发者追捧呢?
是的,大家都是打工人,天天996都嫌时间不够,没时间替别人踩坑,用的人多的坑少,肯定是极为优秀的,去看人家的issues,目前就一个open的,说明人家处理快,反馈及时,star的人这么多,还能做到这种程度,优秀的不得了。
2、但纵观整个类库,还是觉得总体质量不高,一个工具类无所不能在某些时候确实很爽,但是耦合性很高。
总体质量不高你举个感觉不高的例子呢,人家代码规范,注释完整,单元测试做的特别好,不知道你所谓质量高是要求有多高,用的不爽踩一把的见过不少,踩了坑吐槽一下也很正常,你这自己都感觉用的时候确实很爽了,还要踩一把,怎么你是郑爽的爽?耦合性也很高这点,人家都尽量只依赖jdk了,几个模块又可以分开引入,不知道你所谓耦合性高是指的啥
3、相比,更喜欢使用Apache开源的各种Commons类库
喜欢用Commons类库就用呗,我也用这套类库,你怎么方便怎么来,两者功能都是完善的,不用相比,指点江山踩一捧一的,不知道的还以为你是Commons类库的开发者呢
4、不知道各位优秀的开发人员怎么看待
我不是优秀的开发人员,就是普通码农,我觉得你行你上,你也搞一个10k+star的开源工具库,那你们大神之间互相想怎么吐槽怎么吐槽,我等菜鸟安静吃瓜,不行的话,你我都是菜逼,在这bb未免自我意识太过剩
我记得还有一个类似的 Nutz,恰好给这两个社区(Apache)都提过代码。
开源不分高贱,各自有各自的用途,经常写一些连 Spring 都用不到的小程序,Toolkit就挺适合的。作为用户应当知道什么时候该用什么时候不该用。
抑Hutool扬Apache这事取不得。
最近公司的一个应用报告了一个hutool 的漏洞,目前用的是5.x的某个版本,然后升级到5.x最新的版本,编译报错,发现是api调整了。
代码烂不烂无所谓,覆盖率高不高也无所谓,但是兼容性问题,我无话可说。
2025-01-06 更新
看到有很多人好奇是什么漏洞和哪个地方不兼容,今天有时间更新下。
之前说的漏洞信息,我们使用的版本是5.5.1,低于5.8.21的都存在安全漏洞。


漏洞描述
另外不兼容的api是StrUtil里面的一个split方法


5.5.1


5.8.27
5.8.27的StrUtil是继承CharSequenceUtil,而split相关的方法也都移到了CharSequenceUtil这个类里面。
如果不清楚什么叫语义化版本的可以看看文档
语义化版本 2.0.0?semver.org/lang/zh-CN/
看了很多篇优质回答,确切感受到了各路大神的精湛技术,本人也来说说自己的看法。
第一次使用“Hutool”工具库,是在写一个Java包扫描工具类的时候,功能就是扫描指定包路径下的所有jar文件中的class类,并保存在一个Set<Class<?>>集合中。由于当时本人的能力有限(大二学习Java没多久),始终无法解决这个问题,在百度上也搜了好多篇回答,最终挑选了一段个人觉得最好的代码,复制粘贴到本地IDE,完美运行。后来个人学习中多次用到这段代码,每次都复制粘贴这个工具类,直到有一天,我在网上看见了一个名叫“Hutool”的工具库,其中有一个静态方法叫:

public static Set<Class<?>> scanPackage() {
    return ClassScanner.scanPackage();
}

public static Set<Class<?>> scanPackage(String packageName) {
    return ClassScanner.scanPackage(packageName);
}

瞬间整个人都惊呆了,这个世界上这么会有这么懂我的人,一行代码直接解决了我的痛点需求。从此我就陷入了“Hutool”工具库的温柔乡。至此以后,凡是Java项目,我第一件事情就是:

<dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.7.21</version>
</dependency>

我承认,过度依赖于工具库,会使编程能力在一定程度上缺少锻炼,但是不得不承认的是,“Hutool”工具库真的给了我太多“贴心的帮助”,在很多难缠的业务需求中,我都习惯性地先看看“Hutool"工具库中有没有现成的解决方案,在享受帮助的同时,偶尔也会点进去查看一下源码,并惊叹于那些巧妙的设计(相比于本人能力)。
巧合的事情是,我的本科毕业设计是实现一个轻量级的JavaWeb的开发框架,其中包含内置Tomcat、IOC容器、AOP切面设计、Log日志模块、JDBC数据持久化模块等众多模块,我在几个月地反复琢磨下,终于完成了作品的雏形,在各类功能测试中,也实现了基本通过。可是离“轻量级”三个字差的有点远,无论是作品本身的设计以及使用上,都有愧于轻量级三个字,于是我在论文写完后,将我的Web框架进行了彻彻底底的重构。
这次重构是完全基于“Hutool”工具库的,秉承着一切已有轮子不再造的理论,我最终做到了整个框架仅依赖“Hutool”和MySQL驱动,上图:


日志模块、数据持久化模块、Web容器模块完全由”Hutool“工具类提供的各类方法实现。将这个Web框架重构完以后,我才惊奇的发现,原来它是这么的强大,以至于我平时使用的那几个静态方法不过是冰山一角而已。同时我也对原作者致以最高的敬意,起码他在我的毕业论文作品上,立下了汗马功劳。
如何看待”Hutool“工具类广受欢迎?对于我来说是因为它恰好懂我的心吧,哈哈哈。
公司做的是 toB 项目,我还挺喜欢这个库的。平时做什么事情会下意识先看看这个库是不是已经写了。不过有一些地方也是需要逐渐完善的,目前也没有什么问题,稳定性最重要
- Update 2021/10/8
劝退了,今天因为这个库加班了四个小时,把工程中大部分用到这个库的地方换成 apache 和别的库了
这次版本我大量使用这个库做一些业务,这还没进入测试阶段,今天代码 review,同事们发现这个用起来还是有很大的问题,于是开始蛋疼地改用别的库。目前基本保证了主流程没问题,一时也没法全部改完,计划未来一步步迭代去掉。被劝退后,组里的老哥还一直调侃我说,之前不是极其推崇大家使用这个库么?
回想一下,大概是大二那会儿,这个库其实就挺火了,感觉学校做的一些小玩意用这个真的挺方便的,但公司里的工程不大建议用
这个库功能丰富而强大,但是怎么说呢,不大礼貌地评价,就是「格局小了」。
例如,把 CSV 注释符这种非 CSV 协议标准的特性强制要求用户使用,作为库默认处理。这个的意思就是说,如果 CSV 文件有注释符那么就没办法被正确处理了。
对于 CSV 文件的读取,默认实现是一次性读取到内存,而不提供类似 IO 流一样的流式读,我们的工程用的库是 2010 年的了?默认提供的就是流式读,调研其他的库也提供流式读的方法。另一方面 hutool 的单元测试覆盖率的确是个问题。
hutool 教会我的一个道理可能是并不是每个库都像 guava 或者 apache 那么稳定,或者十年后仍然可用
这些问题也有在仓库提过 issue,我也相信这个库也也会变得越来越好
总之平时搞些小玩意还可以耍耍的,但是以后在做大的工程时不会选择它了。业务总得要搞,版本总得要发,再见了,hutool!
谦逊,共享,学习是开源精神的重要组成部分。不一定要是完美的,或者达到一定高度的代码才有资格开源。
我们可以说人家代码质量不高,并讨论相关的代码和内容,有兴趣的话还可以亲自改一改。但是不能理所当然的觉得:这个代码质量不高,还开源,竟然还那么多★。看过Robert C. Martin随书附赠的开源代码吗?那才叫一个质量不高,但是uncle bob将其依旧开源上供人下载与书本一同练习,人家丝毫不会考虑所谓的资格,身份的问题。
公众号:赵侠客一、引言
Hutool这个工具应该是家喻户晓了,它是一个开源的Java工具类库,提供了丰富的静态工具方法来简化Java开发中的常见代码。今天本来是想尝鲜体验一下Hutool新版本都更新了什么新功能,于是从5.x.x升到到了6.0.0,然后就出现了各种包名不存在的错误,我当时就蒙了。


图:Hutool升级6.0后报错
回想当年Mybatis-Plus从2.0升级到3.0时所有包名及方法都需要改一遍的痛苦经历仍然历历在目,至今还有很多项目在使用Mybatis-Plus2.0,因为升级修改的太多了,真的太痛苦了,干脆就不升级了。难道Hutool要重蹈Mybatis-plus的覆辙了?如果你使用了Hutool,以后想要升级到6.0时,那么你将要把所有的包名都改一遍,因为Hutool从5.0升级到6.0后包名全改了!!!


图:StrUtil在Hutool 5.0包名为cn.hutool.*


图:StrUtil在Hutool 6.0包名为org.dromara.hutool.*
Hutool的作者Looly在gitee上也回应了6.0包名修改,说是为了兼容性考虑!!!


图:Hutool 作者回应更改报名二、为什么改包名
作者说更改包名是为了大改后能兼容,那为什么包名改成org.dromara?。在搞清为什么要将包名改为org.dromara前我们需要搞清楚这个dromara是什么?从官网介绍来看dromara是一个聚集了一群开源爱好者的非赢利性组织,可以认为是中国版的Apache,那么就很好理解了,开源项目加入Apache那包名肯定要改成org.apache了。


图:Dromara官网
从Dromara 发布的消息来看,Hutool早在2021年3月15号就加入了该组织


图:Dromara宣布Hutool加入
Dromara社区旗下的顶级项目除了Hutool外还有很多我们耳熟能详的项目,我用过的就有:流程引擎框架LiteFlow、ElasticSearch客户端easy-es。


图:Dromara社区的顶级项目
现在大家应该明白Hutool为什么要把包名改成org.dromara了吧?
三、主要改了哪些包名修改,包名变更为org.dromara.hutool重新整理规整,内部工具类重新整理规整,减少无用模块,工具类归类到对应package中重构Http模块,被人诟病的http模块做重构,采用门面模式,支持包括HttpUrlConnection、HttpClient4、HttpClient5、OkHttp3等库。性能优化,在能力范围之内尽量做性能优化,不跟其他高性能库“攀比”。做减法,相比5.x版本做减法,大部分工作是删掉一些重复代码和无用的重载,使用上可能会增加代码量,但是相比减少了歧义统一构造方法,构建一种对象不再使用混乱的createXXX、newXXX、ofXXX等名字,而是统一使用of或者ofXXX。
包名修改、重新整理规整
Util工具类修改了包名,不仅将所有的cn.hutool改成org.dromara.hutool,还按工具类的用途做了分包, 如字符串类工具类移到了org.dromara.hutool.core.text.,集合类的移到了 org.dromara.hutool.core.collection,时间的移到org.dromara.hutool.core.date*
5.0常用工具类

cn.hutool.core.util.StrUtil.isEmpty("admin");
cn.hutool.core.collection.CollUtil.isEmpty(new ArrayList<>());
cn.hutool.core.date.DateUtil.now();

6.0常用工具类

org.dromara.hutool.core.text.StrUtil.isEmpty("admin");
org.dromara.hutool.core.collection.CollUtil.isEmpty(new ArrayList<>());
org.dromara.hutool.core.date.DateUtil.now();

重构Http模块
5.0HttpUtill使用方法

 cn.hutool.http.HttpUtil.get("https://www.baidu.com");

6.0使用了门面模式+依赖SPI机制提供可选引擎

//默认使用 org.dromara.hutool.http.client.engine.httpclient5.HttpClient5Engine
org.dromara.hutool.http.HttpUtil.get("https://www.baidu.com");    
        
final ClientEngine engine = new OkHttpEngine();
final Request req = Request.of("https://www.baidu.com/").method(Method.GET);
final Response res = engine.send(req);
log.info(res.body().getString());


final ClientEngine jdkHttpEngine = HttpUtil.createClient("jdkClient");
final Response send = jdkHttpEngine.send(Request.of("https://www.baidu.com").method(Method.GET));
log.info(send.body().getString());

//目前支持4种HTTP引擎
org.dromara.hutool.http.client.engine.httpclient5.HttpClient5Engine
org.dromara.hutool.http.client.engine.httpclient4.HttpClient4Engine
org.dromara.hutool.http.client.engine.okhttp.OkHttpEngine
org.dromara.hutool.http.client.engine.jdk.JdkClientEngine 

四、更多其它不兼容修改StrUtil

- StrUtil.utf8Bytes(data));
+ ByteUtil.toUtf8Bytes(data));

NumberUtil

- import cn.hutool.core.util.NumberUtil;
+ import org.dromara.hutool.core.math.NumberUtil;

ArrayUtil

- import import cn.hutool.core.util.ArrayUtil;
+ import import org.dromara.hutool.core.array.ArrayUtil;

ObjectUtil

- cn.hutool.core.util.ObjectUtil.isNotEmpty(obj)
+ org.dromara.hutool.core.util.ObjUtil.isNotEmpty(obj)

lambda整体结构、命名都规范了,以SerXxx开头

- import cn.hutool.core.lang.func.Func1;
+ import org.dromara.hutool.core.func.SerFunction;
- import cn.hutool.core.lang.Filter;
+ import java.util.function.Predicate;

修改Base64

- cn.hutool.core.codec.Base64Encoder.encode(encryptAesKey);
+ org.dromara.hutool.core.codec.binary.Base64.encode(encryptAesKey);
- cn.hutool.core.codec.Base64Decoder.decode(pubKey);
+ org.dromara.hutool.core.codec.binary.Base64.decode(pubKey);

generateKey

- cn.hutool.crypto.SecureUtil.generateKey(str)
+ org.dromara.hutool.crypto.KeyUtil.generateKey(str)

反射操作field

- cn.hutool.core.util.ReflectUtil.getFields(clazz)
+ org.dromara.hutool.core.reflect.FieldUtil.getFields(clazz)
- ReflectUtil.setFieldValue(clientPrincipal, "authorities", authorities);
+ FieldUtil.setFieldValue(clientPrincipal, "authorities", authorities);

日期时间

- cn.hutool.core.date.LocalDateTimeUtil
- cn.hutool.core.date.DateUtil.date()
- cn.hutool.core.date.DateUtil;
+ org.dromara.hutool.core.date.DateUtil;
+ org.dromara.hutool.core.date.DateUtil.now();

dfa

- import cn.hutool.dfa.WordTree;
+ import org.dromara.hutool.core.text.dfa.WordTree;
- cn.hutool.core.text.replacer.ReplacerChain#replace(str)
- org.dromara.hutool.core.text.replacer.ReplacerChain#apply(str)

Dict

- import cn.hutool.core.lang.Dict;
+ import org.dromara.hutool.core.map.Dict;

JSONObject

- jsonObject.putOpt(key,value).putOpt(key,value)

UtilException

- cn.hutool.core.exceptions.UtilException

FileUtil

- import cn.hutool.core.io.FileUtil;
+ import org.dromara.hutool.core.io.file.FileUtil;
- FileUtil.exist(file))
+ FileUtil.exists(file))
-FileUtil.cleanEmpty
- cn.hutool.core.io.FileUtil.extName(filePath)
+ org.dromara.hutool.core.io.file.FileNameUtil.extName(filePath)

CollUtil

- cn.hutool.core.collection.CollUtil.newArrayList(obj);
+ org.dromara.hutool.core.collection.ListUtil.of(obj);
- CollUtil.split(phones, 200);
+ CollUtil.partition(phones, 200);
-ArrayUtil.toArray


tree

- cn.hutool.core.lang.tree.Tree;
- cn.hutool.core.lang.tree.TreeNode;
- cn.hutool.core.lang.tree.TreeUtil;
+ org.dromara.hutool.core.tree.MapTree;
+ org.dromara.hutool.core.tree.TreeNode;
+ org.dromara.hutool.core.tree.TreeUtil;

create -> of

- cn.hutool.json.JSONConfig.create()
- Xxx.create()
+ org.dromara.hutool.json.JSONConfig.of()
+ Xxx.of()

ReUtil

- cn.hutool.core.util.ReUtil.RE_CHINESE;
+ org.dromara.hutool.core.regex.PatternPool.CHINESE;

DefaultSegment

- cn.hutool.core.lang.DefaultSegment#getStartIndex
+ org.dromara.hutool.core.lang.range.DefaultSegment#getBeginIndex

http

- cn.hutool.http.HttpUtil.post(url, data, timeout)
+ org.dromara.hutool.http.HttpGlobalConfig.setTimeout(TIMEOUT);
+ org.dromara.hutool.http.HttpUtil.post(url, data)
- cn.hutool.http.HttpUtil.toParams(map)
+ org.dromara.hutool.core.net.url.UrlQueryUtil.toQuery(map)

BeanUtil

- cn.hutool.core.bean.BeanUtil;
- cn.hutool.core.bean.copier.CopyOptions;
+ org.dromara.hutool.core.bean.BeanUtil;
+ org.dromara.hutool.core.bean.copier.CopyOptions;

EnumUtil

- cn.hutool.core.util.EnumUtil;
+ org.dromara.hutool.core.util.EnumUtil;

IdUtil

- cn.hutool.core.util.IdUtil;
+ org.dromara.hutool.core.data.id.IdUtil;

RegexPool

- cn.hutool.core.lang.RegexPool
+ org.dromara.hutool.core.regex.RegexPool

URLDecoder

- cn.hutool.core.net.URLDecoder;
+ org.dromara.hutool.core.net.url.URLDecoder;

SpringUtil

- cn.hutool.extra.spring.SpringUtil;
+ org.dromara.hutool.extra.spring.SpringUtil;

SecureUtil

- cn.hutool.crypto.SecureUtil;
- cn.hutool.crypto.asymmetric.KeyType;
- cn.hutool.crypto.symmetric.AES;
- cn.hutool.core.util.HexUtil;
- cn.hutool.crypto.BCUtil;
- cn.hutool.crypto.SmUtil;
- cn.hutool.crypto.asymmetric.SM2;
- cn.hutool.crypto.symmetric.SM4;
+ org.dromara.hutool.crypto.SecureUtil;
+ org.dromara.hutool.crypto.asymmetric.KeyType;
+ org.dromara.hutool.crypto.symmetric.AES;
+ org.dromara.hutool.core.codec.HexUtil;
+ org.dromara.hutool.crypto.asymmetric.SM2;
+ org.dromara.hutool.crypto.symmetric.SM4;
+ org.dromara.hutool.crypto.bc.BCUtil;
+ org.dromara.hutool.crypto.bc.SmUtil;

ImgUtil

- cn.hutool.core.img.ImgUtil;
+ org.dromara.hutool.swing.img.ImgUtil;

RandomUtil

- cn.hutool.core.util.RandomUtil;
+ org.dromara.hutool.core.util.RandomUtil;
- cn.hutool.core.io.IORuntimeException;
- cn.hutool.system.SystemUtil;
- RandomUtil.randomEleList(WORDS, wordCount);
+ RandomUtil.randomEles(WORDS, wordCount);

Captcha

- cn.hutool.core.img.FontUtil;
- cn.hutool.captcha.CaptchaUtil;
- cn.hutool.captcha.CircleCaptcha;
- cn.hutool.captcha.GifCaptcha;
- cn.hutool.captcha.LineCaptcha;
- cn.hutool.captcha.ShearCaptcha
+ org.dromara.hutool.swing.captcha.CaptchaUtil;
+ org.dromara.hutool.swing.captcha.CircleCaptcha;
+ org.dromara.hutool.swing.captcha.GifCaptcha;
+ org.dromara.hutool.swing.captcha.LineCaptcha;
+ org.dromara.hutool.swing.captcha.ShearCaptcha

IoUtil

- cn.hutool.core.io.IoUtil;
+ org.dromara.hutool.core.io.IoUtil;

sm2

- (sm2.decryptFromBcd(content, KeyType.PrivateKey));
+ (sm2.decrypt(content, KeyType.PrivateKey));
- sm2.encryptBcd(content, KeyType.PublicKey);
+ sm2.encryptHex(content, KeyType.PublicKey);

五、总结
? ?国产开源软件能靠自己活下来都挺不容易,被开源组织收编也是不错的出路,就是苦了我们这些开发者,全国使用Hutool的项目不在少数,针对这次重大改动本文提出一下几点建议:
重度依赖,这种项目最好就不要升级了,继续使用5.0,作者说了5.0也会继续维护轻度依赖,如果只是用了一些简单的工具类,全局替换包名升级还是可以的新项目,我们需要思考有没有必要使用Hutool,是不是可以使用JDK17?很多新功能JDK都自带了,自己项目组是不是也应该维护起属于自己团队的工具类?
我来客观回答一下。
确实star不能代表一切。?少不代表不好,?多也不代表一定好。但一个开源项目一定是被某些人发现了亮点后口口相传才出现的这么多star。这也是我们认可那些高?开源项目的原因。反正我的一向是只用高?项目,因为在我之前已经有很多人试过毒,我放心。你总说?少不一定不好,那么请你去用?少的项目,等你出了问题哭爹喊娘找不到人帮你解答时,恭喜你,你已经成为我前面说的,替我试毒的那一批人之一,我感谢你,因为你的大公无私让我少了中毒的机会,至于你把项目搞砸了,那管我吊事?我们也素不相识,我只能看着你哭天喊地的提了个万年没人回的issue,默哀两秒钟,然后转向其他的高star的项目。
且我认为你所说的结构差,项目差,不如commons之类的。吐槽它不值这么多star。请你带上自己的开源项目。让我看看你有多少?。谢谢。
再聊一下那些说耦合度,甚至和struts比的某些人,让hutool找定位那些人。瞪大眼睛看一下hutool的介绍,它定位就是一个工具包。放在你的项目里省的你去搜索复制,仅此而已。某些方法你觉得写的烂你可以自己封装,并非你放个工具包进去你就必须用到里面的所有方法。非吹毛求疵的计较这些,有何意义?
我心中的好项目无非就是这几点:
长期维护,避免出现常年老坑。出问题了能尽快得到解答,而不是提个issue等一天。够用就行。用着舒服就行。我就是个码农我并不是每行代码都要写的优雅。尽快搞完回家陪媳妇不香吗?你加班搜索粘贴的时候我已经在回家路上了。并感谢某些工具给我省下陪媳妇的时间。
至于你让项目找定位,呵呵,你不如去自己找找定位看哪个项目该用在哪里。你解决一些日常小问题,那么hutool足够用。你做一些小项目,那hutool足够用。你做一些有严格要求的大项目,那hutool可以起到一点补充。
不要在那吐槽某个工具影响你这 影响你那了,拜托,它只是一个工具。它的使用只跟项目相关,不是和人相关。不是说你这个人不能用这个工具。你就抵触它。就像你处理好文本难道你就要上spring?就要搭一堆框架?高射炮打蚊子??
框架和工具的使用。仅仅适用于适合它的场景。而非其他。还跟commons比的。别秀优越感了行么。个人开发者比不上职业团队好么,代码效率稍微差点不影响你整体效率好么。中文注释不香么,方法全不香么,这些不是加分项吗?你是不是玩个游戏都要跟职业选手比一比?
总而言之,我觉着用的爽,我用。你觉得不爽,你别用。每个人都有自己喜好。这都能理解。
你可以提问hutool和commons哪个好,让大家给一点建议,帮助你选择。但你一上来就贬低hutool。强调你用commons,我就想不明白了。有优越感?优越在哪?我愣是没想明白你想要什么回答。
[收藏本文] 【下载本文】
   科技知识 最新文章
百度为什么越来越垃圾了?
百度为什么越来越垃圾了?
为什么程序员总是发现不了自己的Bug?
出现在抖音评论区里边的算命真不真?
你认为 C++ 最不应该存在的特性是什么?
为什么 Windows 的兼容性这么强大,到底用了
如何看待Nvidia禁止使用翻译工具将cuda运行
为何苹果搞了十年的汽车还是难产,小米很快
该不该和AI说谢谢?
为什么突破性的技术总是最先发生在西方?
上一篇文章      下一篇文章      查看所有文章
加:2025-05-14 13:27:13  更:2025-05-14 14:19:13 
 
 
股票涨跌实时统计 涨停板选股 分时图选股 跌停板选股 K线图选股 成交量选股 均线选股 趋势线选股 筹码理论 波浪理论 缠论 MACD指标 KDJ指标 BOLL指标 RSI指标 炒股基础知识 炒股故事
网站联系: qq:121756557 email:121756557@qq.com  天天财汇