开发者应该避免使用的6个Java功能(转)
本文作者是一名拥有多年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应用程序里直接使用CGLIB或ASM,我可能会立即跑开。
最糟糕的事情莫过于在编译期间没有任何可执行的代码。实际上,当产品在运行时,你根本不知道哪块代码在运行。所以,当你遇到麻烦时,会自然地把错误抛给运行时故障排除和调试,不过这样反而会更麻烦。
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,开发者不妨尝试下。
http://www.iteye.com/news/28388
http://www.infoq.com/cn/news/2013/11/six-java-features-to-avoid
开发者应该避免使用的6个Java功能(转)的更多相关文章
- 20个开发人员非常有用的Java功能代码
本文将为大家介绍20个对开发人员非常有用的Java功能代码.这20段代码,可以成为大家在今后的开发过程中,Java编程手册的重要部分. 1. 把Strings转换成int和把int转换成String ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 【开发者笔记】插入排序过程呈现之java内置GUI表示
先给代码,再给过程视频: package com.dyi.wyb.sort; import java.awt.Color; import java.awt.Graphics; import java. ...
- 【开发者笔记】冒泡排序过程呈现之java内置GUI表示
自己玩玩写写,排序的过程多么有趣,特别是把看着电脑吧一堆乱七八糟的数据排成有序组合的时候,看起来贼舒服,特别是强迫症患者.好了,话不多说上代码,也算是自己记录一下吧,没有什么技术含量但个人感觉比较有趣 ...
- 【开发者笔记】归并排序过程呈现之java内置GUI表示
在网上看到一个视频将各种排序用视频表示出来,配上音乐,挺好玩的样子,就算是不会编程的人看到也会觉得很舒服,碰巧我也正在写归并算法,于是就用java的GUI实现一个. 归并排序的时间复杂度是T(n)=O ...
- APICloud开发者进阶之路 |纯手工编写日程表功能
本文出自APICloud官方论坛, 感谢论坛版主 赵永亮 的分享. 最近看论坛内关于极光推送的问题有很多, 本想写一个关于极光的详细教程的,无奈已经有很多大牛分享过了,所以只得纯手工写了一个日程表,可 ...
- 如何把Java代码玩出花?JVM Sandbox入门教程与原理浅谈
在日常业务代码开发中,我们经常接触到AOP,比如熟知的Spring AOP.我们用它来做业务切面,比如登录校验,日志记录,性能监控,全局过滤器等.但Spring AOP有一个局限性,并不是所有的类都托 ...
- Java开发者必备的10大学习网站,送给入门学习java的你,请收下!
作为开发者来说,必备的除了对编码的热情还要有自己的一套技巧,另外不可缺少的就是平时学习的网站.以下本人收集的 Java 开发者必备的网站,这些网站可以提供信息.以及一些很棒的讲座 , 还能解答一般问题 ...
- 【转载】开发者眼中的Spring与Java EE
转载自:http://www.infoq.com/cn/news/2015/07/spring-javaee 在Java社区中,Spring与Java EE之争是个永恒的话题.在这场争论中,来自两个阵 ...
随机推荐
- 安全的PHP代码编写准则(转)
绝不要信任外部数据或输入 关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据.外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据.在采取措施 ...
- 警告"Local declaration of 'XXX' hides instance variable"原因
Local declaration of 'XXX' hides instance variable 是因为本地变量名跟函数变量名同名 ,.在命名上要注意.....
- [转] 用PDB库调试Python程序
Python自带的pdb库,发现用pdb来调试程序还是很方便的,当然了,什么远程调试,多线程之类,pdb是搞不定的. 用pdb调试有多种方式可选: 1. 命令行启动目标程序,加上-m参数,这样调用my ...
- IDL绘制黑体辐射曲线
普朗克定律是热红外遥感中常常使用的三大定律之一,描述了黑体辐射能量的情况.绝对黑体的辐射光谱对于研究一切物体的辐射规律具有根本的意义.1900年普朗克引进量子概念,将辐射当做不连续的量子发射,成功地从 ...
- vim中选择匹配文本删除技巧
试举几例如下: 如何只保留匹配内容行而删除其他行? :v/pattern/d :help :v 如何对每行只保留匹配内容而删除这一行中的其它内容 :%s/^.pattern.$/\1/g 删除包含特定 ...
- python-Pickle序列化
[Python之旅]第三篇(二):Pickle序列化 python 序列化 pickle 摘要: 说明:关于Pickle的说明 作如下说明: 1 2 3 4 5 6 7 序列化的概念很简单 ...
- (转)php 函数名称前的@有什么作用
如:$register_globals = @ini_get('register_globals'); 隐藏错误提示~如果ini_get('register_globals'); 语句错误的话`错误会 ...
- JavaScript实现弹框
提起JS弹框,我首先想到的是Alert,然后想到的还是Alert,最后我竟然就只知道Alert.然后面试就死在这个Alert上了.恼火. 根据网上各位大神的总结,我整理了一下,也顺便学习了一下. 一. ...
- CXF自动生成客户端
官网下载apache-cxf-3.1.6,bin目录下.配置环境变量,生成客户端 http://blog.csdn.net/jaune161/article/details/25499939 http ...
- Knockoutjs官网翻译系列(一)
最近马上要开始一个新项目的研发,作为第一次mvvm应用的尝试,我决定使用knockoutjs框架.作为学习的开始就从官网的Document翻译开始吧,这样会增加印象并加入自己的思考,说是翻译也并不是纯 ...