关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JAVA »你应该远离的6个Java特性

    你应该远离的6个Java特性

    2015-03-09 00:00:00 出处:codeceo
    分享

    我曾花费了无数个小时为各种不同的应用排错。根据过往的经验我可以得出这样一个结论,那就是对于大多数开发者来说,你应该远离几个Java SE特性或是APIs。这里所说的大多数开发者指的是一般的Java EE开发者而不是库设计者或是基础设施开发者。

    坦白地说,从长远来看,大多数团队都应该远离如下的Java特性。不过凡事总有例外的情况。如果你有一个强大的团队,总是能够清楚地意识到自己在做什么,那就按照你的想法去做就行。但对于大多数情况来说,如果你在项目的开发中使用了下面这几个Java特性,那么从长远来看你是会后悔的。

    这些应该远离的Java特性有:

    反射 字节码操纵 ThreadLocal 类加载器 弱引用与软引用 Sockets

    下面对这些特性进行逐个分析,看看为什么普通的Java开发者应该远离他们:

    反射

    在流行的库如Spring和Hibernate中,反射自然有其用武之地。不过内省业务代码在很多时候都不是一件好事,原因有很多,一般情况下我总是建议大家不要使用反射。

    首先是代码可读性与工具支持。打开熟悉的IDE,寻找你的Java代码的内部依赖,很容易吧。现在,使用反射来替换掉你的代码然后再试一下,结果如何呢?如果通过反射来修改已经封装好的对象状态,那么结果将会变得更加不可控。请看看如下示例代码:

    如果这样做就无法得到编译期的安全保证。就像上面这个示例一样,你会发现如果getDeclaredField()方法调用的参数输错了,那么只有在运行期才能发现。要知道的是,寻找运行期Bug的难度要远远超过编译期的Bug。

    最后还要谈谈代价问题。JIT对反射的优化程度是不同的,有些优化时间会更长一些,而有些甚至是无法应用优化。因此,有时反射的性能损失可以达到几个数量级的差别。不过在典型的业务应用中,你可能不会注意到这个代价。

    总结一下,我觉得在业务代码中唯一合理(直接)使用反射的场景是通过AOP。除此之外,你最好远离反射这一特性。

    字节码操纵

    如果在Java EE应用代码中直接使用了CGLIB或是ASM库,那么我建议你好好审视一下。就像方才我提到的反射带来的消极影响,使用字节码操纵所带来的痛苦可能是反射的好几倍之多。

    更糟糕的是在编译期你根本就看不到可执行的代码。从本质上来说,你不知道产品中实际运行的是什么代码。因此在面对运行期的问题以及调试时,你要花费更多的时间。

    ThreadLocal

    看到业务代码中如果出现ThreadLocal会让我感到颤抖,原因有二。首先,借助于ThreadLocal,你可以不必显式通过方法调用就可以传递变量,而且会对这种做法上瘾。在某些情况下这么做可能是合理的,不过如果不小心,那么我可以保证最后代码中会出现大量意想不到的依赖。

    第二个原因与我每天的工作有关。将数据存储在ThreadLocal中很容易造成内存泄漏,至少我所看到的十个永久代泄漏中就有一个是由过量使用ThreadLocal导致的。连同类加载器及线程池的使用,“java.lang.OutOfMemoryError:Permgen space”就在不远处等着你呢。

    类加载器

    首先,类加载器是个很复杂的东西。你必须首先理解他们,包括层次关系、委托机制以及类缓存等等。即便你觉得自己已经精通了类加载器,一开始使用时还是会出现各种各样的问题,很可能会导致类加载器泄漏问题。因此,我建议大家还是将类加载器留给应用服务器使用吧。

    弱引用与软引用

    关于弱引用与软引用,你是不是只知道他们是什么以及简单的使用方式而已?现在的你对Java内核有了更好的理解,那会不会使用软引用重写所有的缓存呢?这么做可不太好,可不能手里有锤子就到处找鼓敲吧。

    你可能很想知道我为什么说缓存不太适用使用软引用吧。毕竟,使用软引用来构建缓存可以很好地说明将某些复杂性委托给GC来完成而不是自己去实现这一准则。

    下面来举个例子吧。你使用软引用构建了一个缓存,这样当内存行将耗尽时,GC会介入并开始清理。但现在你根本就无法控制哪些对象会从缓存中删除,很有可能在下一次缓存中不再有这个对象时重新创建一次。如果内存还是很紧张,又触发GC执行了一次清理,那么很有可能会出现一个死循环,应用会占用大量CPU时间,Full GC也会不断执行。

    Sockets

    java.net.Socket简直太难使用了。我认为它的缺陷归根结底源自其阻塞的本质。在编写具有Web前端的典型的Java EE应用时,你需要高度的并发性来支持大量的用户访问。这时你最不想发生的事情就是让可伸缩性不那么好的线程池呆在那儿,等待着阻塞的Sockets。

    现在已经出现了非常棒的第三方库来解决这些问题,别自己写了,尝试一下Netty吧。

    Java出现至今经历了多次版本更迭,每次也都会有诸多新特性的加入。在日常的Java开发中,你认为存在哪些Java特性是很容易导致问题的呢?作者提到不建议在普通的应用开发中使用反射,不过对于一些框架或库的开发,离开反射实际上是无法实现的,例如Spring、Struts2等框架,那么在一般的Java项目开发中,你觉得哪些地方有使用反射的必要呢?换句话说,如果不使用反射就实现不了功能或是需求。文中作者也不建议使用字节码操纵,实际上一些框架在实现某些功能时是必须要使用的,比如说Spring在实现AOP时就使用了Java的动态代理与CGLib库两种方式来达成的。那么对于一般的Java项目来说,哪些地方需要用到字节码操纵呢?欢迎各位读者畅所欲言,一起讨论这些有趣的话题。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Destoon 模板存放规则及语法参考

    Destoon系统常量与变量

    Destoon系统目录文件结构说明

    Destoon 系统安装指南

    Destoon会员公司主页模板风格添加方法

    Destoon 二次开发入门

    Microsoft 将于 2026 年 10 月终止对 Windows 11 SE 的支持

    Windows 11 存储感知如何设置?了解Windows 11 存储感知开启的好处

    Windows 11 24H2 更新灾难:系统升级了,SSD固态盘不见了...

    小米路由器买哪款?Miwifi热门路由器型号对比分析

    IT头条

    Synology 对 Office 套件进行重大 AI 更新,增强私有云的生产力和安全性

    01:43

    StorONE 的高效平台将 Storage Guardian 数据中心占用空间减少 80%

    11:03

    年赚千亿的印度能源巨头Nayara 云服务瘫痪,被微软卡了一下脖子

    12:54

    国产6nm GPU新突破!砺算科技官宣:自研TrueGPU架构7月26日发布

    01:57

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    技术热点

    最全面的前端开发指南

    Windows7任务栏桌面下角的一些正在运行的图标不见了

    sql server快速删除记录方法

    SQL Server 7移动数据的6种方法

    SQL Server 2008的新压缩特性

    每个Java程序员必须知道的5个JVM命令行标志

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。