阅读更多

2顶
24踩

编程语言

本文作者是一名拥有多年Java开发经验的程序员,他从经验中得出,并不是所有的Java SE功能/API都值得程序员去使用,比如本文列举的这6个,大家在使用前得慎重对待。以下是对原文的摘译。

多年的Java开发经验告诉我,从长远角度来看,以下这些Java SE功能/API,开发者最好停止使用。 

  • Reflection
  • Bytecode manipulation 
  • ThreadLocals
  • Classloaders
  • Weak/Soft references
  • Sockets 

1.Reflection

Reflection即反射,在许多流行的库里面都有反射机制,比如Spring和Hibernate。通过对业务代码进行反思,我建议大家避免使用反射。下面列出我反对使用的原因:

首先涉及到代码可读性/工具支持。打开IDE并且在Java代码里找到相互依赖关系。使用relection替换方法调用,并且试着重复该步骤。事情变的愈发不可收拾,正常情况下都应该封装好了再修改状态。下面来看看具体代码示例:

public class Secret {
    private String secrecy;
    public Secret(String secrecy) {
        this.secrecy = secrecy;
    }
    public String getSecrecy() {
        return null;
    }
}
public class TestSecrecy {
    public static void main(String[] args) throws Exception {
        Secret s = new Secret("TOP SECRET");
        Field f = Secret.class.getDeclaredField("secrecy");
        f.setAccessible(true);
        System.out.println(f.get(s));
    }
}

通过查看以上代码可以得知,方法getDeclaredField()参数只有在运行时才可以被发现。而你也清楚,运行时产生的bug总比不执行脚本要更加棘手。

其次,反射调用优化是由JIT执行的,一些优化可能需要花费很长时间才能得到应用,而有些优化甚至都得不到应用,所以关于反射的性能优化有时会被数量化。但在一个典型的业务应用程序中——你可能不会真正意识到这些性能开销。

总之,开发者应该通过AOP合理地在业务层使用反射,除此以外,你最好离它远远的。

2.Bytecode manipulation.

字节码操作,如果我看到你在Java EE应用程序里直接使用CGLIBASM,我可能会立即跑开。

最糟糕的事情莫过于在编译期间没有任何可执行的代码。实际上,当产品在运行时,你根本不知道哪块代码在运行。所以,当你遇到麻烦时,会自然地把错误抛给运行时故障排除和调试,不过这样反而会更麻烦。

3.ThreadLocals

这里有两个不相关的原因,当我在业务层代码里看到ThreadLocals时会颤抖。首先,在ThreadLocals的帮助里,你可能会看到许多变量的使用都没有通过方法调用链来明确地向下传递。这在某些场合下是有用的,但当你一旦粗心,你会在代码里构建许多意料不到的依赖关系。

第二个不相关的原因与我日常的工作相关,在ThreadLocals里存储数据会引发内存泄露。最起码我遇到的Permgen泄露有十分之一都是使用ThreadLocals造成的,在结合了类加载器和线程池后,“java.lang.OutOfMemoryError:Permgen space”异常可能就马上出现了。

4.Classloaders

首先,类加载器是一个复杂的野兽。你必须先了解它的层次结构、委托机制、类缓存等等。即使你认为自己已经掌握了,它可能还是不能正常工作。最终将导致一个类加载器泄露问题。因此我只能建议你将这个任务留给应用服务器处理

5.Weak/Soft references

现在,你应该更好的理解Java的内部方法。使用软引用来重写所有的缓存并不明智。我知道,当你手上拿着锤子的时候,就会到处寻找钉子。可对于锤子来说,缓存并不是个好钉子。为什么?基于软引用构建缓存可能是如何委托一些复杂因素到GC而不是通过自身实现的一个好例子。

下面举个缓存的例子,你使用软引用来创建数据,当内存被耗尽时,GC进入并且进行清理。但是,缓存中被删除的对象并未得到你的控制,而且很有可能在下一次的cache-miss中重新创建。如果内存仍然不足,你可以触发GC进行再次清理。你可能已经看出了整个运行过程的恶性循环,整个应用程序就变成了CPU与GC不断运行的状态了

6.Sockets 

普通老式的java.net.Socket实在是太复杂,以至于很难弄正确。我觉得阻塞性是其根本性的缺陷。当你编写一个典型的带有Web前端的Java EE应用程序时,应用程序需要高并发度来支持大量的用户,而你现在最不想发生的是不具有可扩展的线程池坐等阻塞套接字。

目前有许多精彩可用的第三方库,使用它们可以更好的完成任务,比如Netty,开发者不妨尝试下。

via:Plumbr

来自: csdn
2
24
评论 共 26 条 请登录后发表评论
26 楼 zidafone 2013-11-07 12:13
alvin198761 写道
zidafone 写道
clxy 写道
我理解作者的意思是说,不要在开发过程中使用这些特性

而是把这些留给服务器(比如Tomcat)或成熟的框架/库(比如Netty),并不是要把这些特性完全踢出Java。

我也不同意第一项,但其他的还是基本同意。
通常的泛用业务开发不该需要直接和这些东东打交道,即便需要开发框架也应该做些封装才好,特别是开发队伍人多且水平参差不齐时...



同意。作者的意思是,这些技术在应用层面的开发不适宜使用,它们是平台、框架、服务器这些级别的开发应该用到的。
反射也有著作反对日常使用的,是effective java还是rod johnson的哪本书来着。它破坏的是java的强类型特性。

如果你做那些插拔式的插件开发,没有反射咋搞


反对日常使用,不是说就不要反射了呀
较高级别的抽象上和一些具体事务上,反射当然是一个利器呀
只是大部分日常编码,用反射就是牛刀杀鸡
25 楼 alvin198761 2013-11-06 09:01
zidafone 写道
clxy 写道
我理解作者的意思是说,不要在开发过程中使用这些特性

而是把这些留给服务器(比如Tomcat)或成熟的框架/库(比如Netty),并不是要把这些特性完全踢出Java。

我也不同意第一项,但其他的还是基本同意。
通常的泛用业务开发不该需要直接和这些东东打交道,即便需要开发框架也应该做些封装才好,特别是开发队伍人多且水平参差不齐时...



同意。作者的意思是,这些技术在应用层面的开发不适宜使用,它们是平台、框架、服务器这些级别的开发应该用到的。
反射也有著作反对日常使用的,是effective java还是rod johnson的哪本书来着。它破坏的是java的强类型特性。

如果你做那些插拔式的插件开发,没有反射咋搞
24 楼 zidafone 2013-11-02 09:57
clxy 写道
我理解作者的意思是说,不要在开发过程中使用这些特性

而是把这些留给服务器(比如Tomcat)或成熟的框架/库(比如Netty),并不是要把这些特性完全踢出Java。

我也不同意第一项,但其他的还是基本同意。
通常的泛用业务开发不该需要直接和这些东东打交道,即便需要开发框架也应该做些封装才好,特别是开发队伍人多且水平参差不齐时...



同意。作者的意思是,这些技术在应用层面的开发不适宜使用,它们是平台、框架、服务器这些级别的开发应该用到的。
反射也有著作反对日常使用的,是effective java还是rod johnson的哪本书来着。它破坏的是java的强类型特性。
23 楼 zoozooll 2013-10-28 09:19
作者是中国人,可以直接忽略了。
22 楼 alvin198761 2013-10-27 11:39
搞C,C++,汇编的人直接不用活了,他们写的代码一句没注意就会出现大坑
21 楼 alvin198761 2013-10-27 11:37
照留住这么说,java时候写 hello world
再说一点,楼主的反射代码写的会出问题,应该放到 访问控制里面去,
照这种心态,大家不要用煤气,电磁炉,不要生火做饭,不要用微波炉,不能用绞肉机,......
不要生孩子,不要在公路上走,不要旅游,不要爬山,不要搞火箭什么的...
在中国,不要吃东西,不要喝东西,不要呼吸...
20 楼 yanqingluo 2013-10-26 21:36
应用代码确实要避免这些。
这些是容器和框架需要用的技术。
19 楼 accp_huangxin 2013-10-26 19:56
天天在用这些东西,java之所以强大,跟这些东西是分不开的
18 楼 jianfeng 2013-10-25 09:49
脑残吗,高级应用被说的一文不值,tomcat源码几乎覆盖了这里的所有东西。不解释 楼猪脑残一个
17 楼 xucaishen 2013-10-24 10:47
说实在的,比较容易误导别人的文章。。。能深刻解读的还行,对于一般人云亦云的开发者来说,真是非常容易误人子弟。
16 楼 Shen.Yiyang 2013-10-23 19:36
避免直接使用是很有道理的,但不是绝对的禁用。开发团队对这类API要做的首要工作是再封装,给专注业务逻辑的开发足够的支持。
15 楼 socao 2013-10-23 15:04
其实我感觉作者说的有点道理,只是标题是不是该修改一下,入门级慎用。
14 楼 badqiu 2013-10-23 12:39
垃圾文章。
13 楼 moyan_java 2013-10-23 12:00
说的有自己的道理,但也仅代表个人的一种观点。工程和学术还是有些不一样的出发点的。
12 楼 lection.yu 2013-10-23 11:20
呵呵。比较酷的都不建议用。。
11 楼 Tyrion 2013-10-23 11:19
因噎废食的主张。
建议标题改成“初级开发者应该避免使用的6个Java功能”
10 楼 503718696 2013-10-23 10:36
我觉得反射,开源软件好用,商业软件混淆很是麻烦。有更好的解决方案吗?
9 楼 yanglphf 2013-10-23 09:38
是因为学习成本高,开发后不易于维护吧
8 楼 clxy 2013-10-22 19:48
我理解作者的意思是说,不要在开发过程中使用这些特性

而是把这些留给服务器(比如Tomcat)或成熟的框架/库(比如Netty),并不是要把这些特性完全踢出Java。

我也不同意第一项,但其他的还是基本同意。
通常的泛用业务开发不该需要直接和这些东东打交道,即便需要开发框架也应该做些封装才好,特别是开发队伍人多且水平参差不齐时...
7 楼 fjjiaboming 2013-10-22 18:26
小白.  

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • Java基础学习总结(174)——Java 开发者应该会的流程图绘制技巧

    流程图 (Flow Chart )是流经一个系统的信息流、观点流或部件流的图形代表。在企业中,流程图主要用来说明某一过程。这种过程既可以是生产线上的工艺流程,也可以是完成一项任务的管理过程。流程图是揭示和掌握封闭...

  • java--开发者应该避免使用的6个Java功能

    多年的Java开发经验告诉我,从长远角度来看,以下这些Java SE功能/API,开发者最好停止使用。  ReflectionBytecode manipulation ThreadLocalsClassloadersWeak/Soft referencesSockets  1.Reflection ...

  • Java六功能开发者应避免

    作为一名拥有多年Java开发经验的程序员,他从经验中得出,并不是所有的Java SE功能/API都值得程序员去使用,比如本文列举的这6个,大家在使用前得慎重对待。以下是对原文的摘译。  多年的Java开发经验告诉我,从...

  • 应避免使用的6个Java功能

    本文作者是一名拥有多年Java开发经验的程序员,他从经验中得出,并不是所有的Java SE功能/API都值得程序员去使用,比如本文列举的这6个,大家在使用前得慎重对待。以下是对原文的摘译。 多年的Java开发经验告诉我,...

  • JDK 14全景透视:每个Java开发者必知的新特性

    本文将全面探讨JDK 14引入的新特性和改进。从语言的增强到性能的提升,再到新工具的引入,JDK 14标志着...无论你是刚接触Java还是经验丰富的开发者,本文将提供你需要了解的关键信息,帮助你充分利用JDK 14的强大功能。

  • 面向Java开发者的ChatGPT提示词工程(6)迭代改进提示词

    但是,对于更成熟的应用程序,评估提示词在多个资料简介上的表现可能是有用的,例如在多个资料简介上测试不同的提示词,以查看其在平均或最差情况下的表现如何。虽然第一次写的提示词可能会有一定的可用性,但最重要...

  • 开发者应该避免的6个JAVE

    本文作者是一名拥有多年Java开发经验的程序员,他从经验中得出,并不是所有的Java SE功能/API都值得程序员去使用,比如本文列举的这6个,大家在使用前得慎重对待。以下是对原文的摘译。 多年的Java开发经验告诉我...

  • 《2022年Java开发者生产力报告》出炉啦

    2022 年,Perforce 公司没有「爽约」,《2022年 Java 开发人员生产力报告》如期而至。 该报告基于对全球 Java 开发专业人士的调查,持续时间为 2021 年 10 月到 2022 年 1 月,共收到了 876 份回复,报告涵盖有关 ...

  • Java常见设计模式总结

    设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件工程的基石,如同大厦的一块块...

  • 真相:Java 开发者钟爱 Kotlin 的五个原因

    现在Kotlin语言越来越流行。它不仅广泛用在移动应用开发上,也能用于...但是,它与Java也很相似,因此任何有经验的Java程序员都能在几个小时之内学会使用Kotlin。 这篇文章中,作者将讨论在服务器端使用Kotlin...

  • 面向Java开发者的ChatGPT提示词工程(4)明确步骤、GPT自己找解决方案

    在之前的文章中,我们了解到了编写明确具体的指令关键原则的四种策略,它们分别是:接下来,我们将继续了解第二个关键原则:给 GPT 一定的“思考”时间。当 GPT 匆忙给出错误结论时,我们可以考虑重新构思问题,并...

  • 【开发者思维】优秀开发者应该具备的25个思维习惯

    即使是做这些小变更也挺麻烦的”“变更之后,软件功能出问题了”“刚修复了这个 bug,却冒出来个新的”“写的是冗余代码”“代码过于复杂,不可能在这基础上添加新特性了”“把这些代码扔掉重写”上面这些话,你觉得...

  • java基础总结(七十七)--Java Instrument 功能使用及原理

    使用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义。有了这样的功能,开发者就可以实现更为灵活的运行时虚拟机监控...

  • Java程序员如何避免开发中的bug出现?给你3个建议

    Java编程语言在IT行业毋庸置疑是企业中不可缺少的,现今企业招收大量Java人才,从Web应用到Android应用,这款语言已经被广泛用于开发各类应用及代码中的复杂功能。 不过在编写代码时,bug永远是困扰每一位从业者的...

  • Java Instrument 功能使用及原理

    0 介绍 利用 java.lang.instrument 做动态 Instrumentation 是 Java SE...使用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某...

  • 你应该远离的6个Java特性

    本文来源于我在InfoQ中文站原创的文章,原文地址是:...近日,Tarnovski撰文谈到了普通开发者应该尽量避免使用的6个Java特性,这些特性

  • 数据库基础测验20241113.doc

    数据库基础测验20241113.doc

  • 微信小程序下拉选择组件

    微信小程序下拉选择组件

Global site tag (gtag.js) - Google Analytics