对于细节问题我一直认识不怎么深刻,改变我这个看法的是很多年前玩dnf的时候,辛辛苦苦刷来一身的史诗装备,最后却发现打出的伤害并没有想象中那么令人满意,甚至令人感到有点沮丧。后来舍友告诉我,你要注意细节打造,各方面细节都关注起来,强化附魔徽章该搞的都搞起来,结果自然是好的,收效很不错。对于代码优化这块也是一样。然而很多人会说,这种小问题有必要吗?你要知道小虾米吃的多了鲸鱼也是能喂饱的!

一个个小细节优化起来,对于代码的维护以及运行效率绝对是大大有益处的。

代码优化细节

1.尽量指定类、方法的final修饰符

带有final修饰符的类是不可派生的。在java核心API中,有多应用的例子,例如java.lang.String,整个类都是final。为类指定final修饰符让类可以不被继承,为方法指定final修饰符了可以让方法不被重写。如果指定了一个类为final,则该类的所有方法都是final的。java编译器会寻找机会内联所有的final 方法,内联对于提升java运行效率作用重大,具体参加java运行期优化。此举能使性能提升平均百分之五十以上。

2.尽量重用对象

特别是String对象的使用,出现字符串连接时应该使用StringBuilder/StringVuffer代替。由于java虚拟机不仅要花时间生成对象,以后可能还要花更多时间对这些对象和垃圾进行回收和处理,因此生成过多对象将会给程序的性能带来很大影响。

3.尽量可能使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中速度较快,其他变量,如静态变量、实例变量等都在堆中创建,速度较慢。另外栈中创建的变量,随着方法的运行结束,这些内容就没了,不需要额外的垃圾回收。

4.及时关闭流

java编译过程中进行数据库连接、I/O流操作时务必小心,在使用完毕后,及时关闭以释放资源。因为对这些大对象的操作会造成系统大的开销,稍有不慎将会导致严重的后果。

5.尽量减少对变量的重复计算

明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时恢复现场等。所以例如下面的操作:

for(int i=0;i<list.size();i++){....}

建议替换为:

for(int i=0, int length=list.size(); i<length;i++){....}

这样,在list.size()很大的时候,就减少了很多的消耗;

6.尽量采用懒加载的策略,即在需要的时候才创建

例如:

String str="aaa";
if(i==1 )
{
list.add(str);
}建议替换为:
if(i==1)
{
String str="aaa";
list.add(str);
}

7.慎用异常

异常对性能不利。抛出异常首先要创建一个新的对象,Throwable接口的构造函数调用名为fillnStackTrace()的本地同步方法,fillnStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,java虚拟机就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于处理错误处理,不应该用来控制程序流程。

8.不要在循环中使用try……catch……,应该把其放在最外层

9.如果能估计到待添加内容的长度,为底层以数组方式实现的集合、工具类指定初始长度

10.当复制大量数据时,使用System.arraycopy()命令

11.乘法除法使用移位操作

例如:
for(val=0; val<10000; val+=5)
{
a=val*8;
b=val/2;
}用位移操作可以极大地提高性能,因为在计算机底层,对为的操作是最方便的、最快的,因此建议修改为:
for (val=0; val<10000; val+=5)
{
a=val << 3
b=val >> 1
}
唯一操作一般不太好理解,使用过程中最好加上注释;

12.循环内不要不断创建对象引用

例如:
for (int I=1; I<=count; I++)
{
Object obj=new Object();
}这种做法会导致内存中有count份Object对象引用的存在,count很大的话,就耗费内存了,更改为:Object obj=null;
for( int I=0; I<=count; I++){
object=new Object();
}这样的话,内存中只有一份Object对象的引用,每次new Object()的时候,object对象引用指向不同的Object罢了,只是内存中只有一份,这样就大大节省了内存空间了;

13.基于效率和类型检查的考虑,应该尽可能使用array,无法确定数组的大小时才使用ArrayList

14.尽量使用HashMap、ArrayList、StringBuilder,除非线程安全需要,否则不推荐使用Hashtable、Vector、StringBuffer,后三者由于使用同步机制而导致了性能开销

15.不要将数组声明为public static final

因为这毫无意义,这样只是定义了引用为static final,数组的内容还是可以随意改变的,将数组声明为public更是一个安全漏洞,这意味着这个数组可以被外部类所改变。

16.尽量在合适的场合使用单例

使用单例可以减轻加载的负担,缩短加载时间、提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:

(1)控制资源的使用,通过线程同步来控制资源的并发访问;

(2)控制实例的产生,以达到节约资源的目的;

(3) 控制数据的共享,在不建立直接关联的条件下,让多个不相关的进程或者线程之间实现通信

18.及时清除不需要的会话

当会话不需要的时候,应当及时调用HtpSession的invalidate()方法清除会话;

19.实现RandomAccess接口的集合比如ArrayList,应当使用最普通的for循环而不是foreach循环来遍历

这是JDK推荐给用户的。JDK API对于RandomAccess接口的解释是:实现RandomAccess接口用来表明其支持快速随机访问,此接口的主要目的是允许一般的算法更改其行为,从而将其应用到随机或连续访问列表时能提供良好的性能。实际经验表明,实现RandomAccess接口的类实例,假如是随机访问的,使用普通for循环效率将高于使用foreach循环;反过来,如果是顺序访问的,则使用Iterator会效率更高。可以使用类似如下的代码作判断:

if (list instanceof RandomAccess)
{ for (int i = 0; i < list.size(); i++){}
}else{
Iterator<?> iterator = list.iterable();
while (iterator.hasNext()){iterator.next()}
}

foreach循环的底层实现原理就是迭代器Iterator,参见Java语法糖1:可变长度参数以及foreach循环原理。所以后半句”反过来,如果是顺序访问的,则使用Iterator会效率更高”的意思就是顺序访问的那些类实例,使用foreach循环去遍历。

20.使用同步代码块替代同步方法

这点在多线程模块中的synchronized锁方法块一文中已经讲得很清楚了,除非能确定一整个方法都是需要进行同步的,否则尽量使用同步代码块,避免对那些不需要进行同步的代码也进行了同步,影响了代码执行效率。

21.将常量声明为static final,并以大写命名

这样在编译期间就可以把这些内容放入常量池中,避免运行期间计算生成常量的值。另外,将常量的名字以大写命名也可以方便区分出常量与变量;

22.不要创建一些不使用的对象,不要导入一些不使用的类

23.程序运行过程中避免使用反射

请参见反射;反射是java提供给用户的一个很强大的功能,功能强大意味着效率不高。不建议在程序运行过程中尤其是频繁使用反射机制,特别是Method的invoke方法,如果确实有必要,一种建议性的做法是将那些需要通过反射加载的类在项目启动的时候通过反射实例化出一个对象并放入内存。因为用户只关心在交互的时候获取最快的响应速度,并不关心醒目启动的时候花多久的时间。

24.使用数据库连接池和线程池

这两个池都是用于重用对象的,前者可以避免频繁地打开和关闭链接,后者可以避免频繁的创建和销毁线程。

25.使用带缓冲的输入输出流进行IO操作

带缓冲的输入流和输出流,即BufferedReader,BufferedWriter、BufferedInputStream、BufferedOutputStream,这可以极大地提升IO效率;

26.顺序插入和随机访问较多的场景使用ArrayList,元素删除和中间插入比较多的场景使用LinkedList这个,理解ArrayList和LinkedList的原理就知道了

27.不要让public方法中有太多的形参

public方法即对外提供的方法,如果给这些方法太多形参的话主要有两点坏处:

1、违反了面向对象的编程思想,Java讲求一切都是对象,太多的形参,和面向对象的编程思想并不契合

2、参数太多势必导致方法调用的出错概率增加

至于这个”太多”指的是多少个,3、4个吧。比如我们用JDBC写一个insertStudentInfo方法,有10个学生信息字段要插如Student表中,可以把这10个参数封装在一个实体类中,作为insert方法的形参。

28.字符串变量和字符串常量eauals的时候将字符串常量写在前面

String str = "123";
if (str.equals("123")) {...}
建议修改为:String str = "123";
if ("123".equals(str))
{
...
}这样做主要是可以避免空指针异常

30.不要对数组使用toString()方法

public static void main(String[] args)
{ int[] is = new int[]{1, 2, 3};
System.out.println(is.toString());
}结果是:
[I@18a992f本意是想打印出数组内容,却有可能因为数组引用is为空导致空指针异常。
不过虽然对数组toString()没有意义,但是对集合toString()是可以打印出集合里面的内容的,
因为集合的父类AbstractCollecttions重写了Object的toString()的方法。

32.公共的集合类中不使用的数据一定要及时remove掉

如果一个集合类是共用的(也就是说不是方法里面的属性),那么这个集合里面的元素是不会自动释放的,因为始终有引用指向它们。所以,如果共用集合里面的某些数据不使用而不去remove掉它们,那么将会造成这个共用集合不断增大,使得系统有内存泄漏的隐患。

33.把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)、数据+ 最慢

34.使用最有效率的方式去遍历map

public static void main(String[] args)
{
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("111", "222");Set<Map.Entry<String, String>> entrySet = hm.entrySet();
Iterator<Map.Entry<String, String>> iter = entrySet.iterator(); while (iter.hasNext())
{
Map.Entry<String, String> entry = iter.next();
System.out.println(entry.getKey() + " " + entry.getValue());
}
}如果你只想遍历一下这个Map的key值,那用“Set keySet = hm.keySet();”会比较适合一些

35.对资源的close()建议分开操作

比如有这么一段代码:
try{
xxx.close();
yyy.close();
}catch(Exceotion e){
....
}建议修改为:
try{
xxx.close();
}catch(Exception e){
....
}try{
yyy.close();
}catch(Exception e){
....
}

虽然这样做有些麻烦,却能避免资源泄漏。万一xxx.close();抛异常了。那么就进入catch 中了,yyy.close()不会执行,yy这块儿资源就不会回收了,一只占用着这样的代码一多,是可能引起资源句柄泄漏的。而改为上面的写法之后,就保证了无论如何xxx和yyy都会被close掉;

提高java代码执行效率的技巧相关推荐

  1. 将m文件通过matlab 的编译器转换为可执行文件,【转】 Matlab中提高m文件执行效率的小技巧...

    在使用数组或矩阵之前先定义维数 MATLAB中的变量在使用之前不需要明确地定义和指定维数.但当未预定义数组或矩阵的维数时,当需赋值的元素下标超出现有的维数时,MATLAB 就为该数组或矩阵扩维一次,这 ...

  2. 提高 Java 代码质量

    高质量代码中往往缺陷更少!确保高的 Java 代码质量有两个步骤:尽早并经常地编写各个层次的测试用例,以及持续的监测质量状况.那么我们又该如何实践呢?本专题汇集了大量来自代码质量专家们的专业经验.最佳 ...

  3. 【Groovy】Groovy 动态语言特性 ( Groovy 语言与 Java 语言执行效率对比 | 以动态特性编译的 Groovy 类 | 以静态特性编译的 Groovy 类 )

    文章目录 一.以动态特性编译的 Groovy 类 二.Groovy 语言与 Java 语言执行效率对比 三.以静态特性编译的 Groovy 类 一.以动态特性编译的 Groovy 类 Groovy 类 ...

  4. 30 个提高Web 程序执行效率的好经验[转]

    1. 尽量避免使用DOM.当需要反复使用DOM 时,先把对DOM 的引用存到JavaScript 本地变量里再使用.使用设置innerHTML的方法来替换document.createElement/ ...

  5. 如何提高Java代码的可重用性?

    提高java代码可重用性有哪些方法措施,以下就讲解了三种关于提高java代码可重用性的措施,一起来了解一下吧~ 改写类的实例方法 通过类继承实现代码重用不是精确的代码重用技术,因此它并不是最理想的代码 ...

  6. 解读30个提高Web程序执行效率的好经验

    其实微博是个好东西,关注一些技术博主之后,你不用再逛好多论坛了,因为一些很好的文章微博会告诉你,最近看到酷勤网推荐的一篇文章<30个提高Web程序执行效率的好经验>,文章写得不错,提到一些 ...

  7. 并行算法:如何利用并行处理提高算法的执行效率?

    时间复杂度是衡量算法执行效率的一种标准.但是,时间复杂度并不能跟性能划等号.在真实的软件开发中,即便在不降低时间复杂度的情况下,也可以通过一些优化手段,提升代码的执行效率.毕竟,对于实际的软件开发来说 ...

  8. java build path entries 为空_TOOLFK工具-在线JAVA代码执行工具

    本文要推荐的[TOOLFK]在线JAVA代码执行工具 ,提供JAVA代码在线执行功能. 網站名稱:ToolFk 網站鏈結:https://www.toolfk.com/ 工具链接:https://ww ...

  9. java解析shell命令_Android中执行java命令的方法及java代码执行并解析shell命令

    这篇文章给大家介绍Android中执行java命令的方法及java代码执行并解析shell命令,需要的朋友一起学习 android中执行java命令的方法大家都晓得吗,下面一段内容给大家带来了具体解析 ...

最新文章

  1. 如何入门生信Linux
  2. python有趣代码-wtfPython―Python中一组有趣微妙的代码【收藏】
  3. boost::hana::at用法的测试程序
  4. python规则框架_Pytest框架【2】:用例规则
  5. kail利用msf工具对ms11-003漏洞入侵渗透Win7
  6. [bzoj3036]绿豆蛙的归宿
  7. 设计模式--单例模式--Java实现
  8. H248协议附加业务--遇忙前转流程
  9. Learning Cocos2d-x for WP8(4)——中文显示
  10. php如何优化递归函数,php递归函数怎么用才有效?php递归函数典型例子
  11. 考研基础高等数学笔记
  12. U盘拷贝时提示文件过大
  13. Channel Access Protocal——EPICS Base-3.16版CA协议 - 字节序与数据类型
  14. 处理BigDecimal字段, java.math.BigDecimal cannot be cast to [Ljava.lang.Object;
  15. it培训和自学的优缺点分析
  16. mysql分区表去重复_MySQL分区表管理
  17. 目标检测数据集VOC 2007/2012 整理
  18. 营养不良和口服万古霉素对人体肠道菌群和营养吸收的影响
  19. MindMapper中的主题该怎样进行修改
  20. 教程-mac版本texpad配置中文环境教程

热门文章

  1. MATLAB生成伯努利图分布,C++ - 随机生成器 伯努利分布(bernoulli distribution) 的 详解 及 代码...
  2. 2021年终总结——分享快乐
  3. C#“正由另一进程使用,因此该进程无法访问该文件”在复制删除SQLite数据库文件时出现
  4. 公告 | CCL 2022 汉语学习者文本纠错评测结果出炉!
  5. java/php/net/python火车票售票系统设计
  6. count(*)和count(1)的区别和性能分析
  7. 【线性代数】标量、向量、矩阵和张量(scalar, vector, matrix tensor)
  8. python 节气_二十四节气
  9. Python读写Excel表格,就是这么简单粗暴又好用(文末免费送资料)
  10. Delta3D Open Source Engine