Java编码技巧之高效代码50例

  • 时间:
  • 浏览:3

正例:

多守护应用应用程序中2个 必要的开销:守护应用应用程序的创建和上下文切换。采用守护应用应用程序池,可不须要尽量地处置哪几种开销。

原理与"何必 使用循环拷贝集合,尽量使用JDK提供的最好的依据 拷贝集合"这类。

协议编程,可不须要@NonNull和@Nullable标注参数,算不算遵循全凭调用者自觉。

不可变的静态常量,着实须要支持多守护应用应用程序访问,也可不须要使用非守护应用应用程序安全类。

正例:

备注:肯能业务比较复杂,可不须要采用Map实现策略模式。

使用缓冲流BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等,可不须要大幅减少IO次数并提升IO下行速率 单位。

正例:

反例:

正例:

直接赋值常量值,却说我创建了2个 对象引用,而你这些 对象引用指向常量值。

反例:

反例:

直接捕获对应的异常,处置用instanceof判断,下行速率 单位更高代码更简洁。

反例:

反例:

反例:

JSON提供把对象转化为JSON字符串、把JSON字符串转为对象的功能,于是被一点人用来转化对象。你这些 对象转化最好的依据 ,着实在功能上这麼 什么的问题,怎样让 在性能上却处于什么的问题。

多2个 类就须要多一份类加载,却说我尽量处置定义何必 要的子类。

反例:

正例:

正例:

Java集合初始化时全部都是指定2个 默认大小,当默认大小不再满足数据需求时就会扩容,每次扩容的时间比较复杂度有肯能是O(n)。却说我,尽量指定预知的集合大小,就能处置或减少集合的扩容次数。

反例:

正例:

正例:

反例:

反例:

直接迭代须要使用的集合,不让通过其它操作获取数据。

正例:

正例:

反例:

在函数内,基本类型的参数和临时变量都保处于栈(Stack)中,访问下行速率 单位较快;对象类型的参数和临时变量的引用都保处于栈(Stack)中,内容都保处于堆(Heap)中,访问下行速率 单位较慢。在类中,任何类型的成员变量都保处于堆(Heap)中,访问下行速率 单位较慢。

使用size最好的依据 来检测空逻辑上这麼 什么的问题,但使用isEmpty最好的依据 使得代码更易读,怎样让 可不须要获得更好的性能。任何isEmpty最好的依据 实现的时间比较复杂度全部都是O(1),怎样让 一点size最好的依据 实现的时间比较复杂度有肯能是O(n)。

反例:

正例:

对于大多数刚接触JDK8的同学来说,全部都是认为Lambda表达式却说我匿名内部管理类的语法糖。实际上, Lambda表达式在大多数虚拟机中采用invokeDynamic指令实现,相对于匿名内部管理类在下行速率 单位上会更高一点。

正例:

正例:

使用非守护应用应用程序安全类,处置了何必 要的同步开销。

提取公共表达式,只计算一次值,怎样让 重复利用值。

正例:

正例:

反例:

String是final类,内容不可修改,却说我每次字符串拼接全部都是生成2个 新对象。StringBuilder在初始化时申请了一块内存,日后 的字符串拼接全部都是这块内存中执行,不让申请新内存和生成新对象。

正例:

使用!取反会多一次计算,肯能这麼 必要则优化掉。

在类的每个对象实例中,每个成员变量全部都是一份副本,而成员静态常量不都可不可否 一份实例。

反例:

其中,可不须要根据实际清况 手动指定缓冲流的大小,把缓冲流的缓冲作用发挥到最大。

使用""+进行字符串转化,使用方便怎样让 下行速率 单位低,建议使用String.valueOf.

转化Object数组时,这麼 必要使用toArray[new Object[0]],可不须要直接使用toArray()。处置了类型的判断,也处置了空数组的申请,却说我下行速率 单位会更高。

反例:

反例:

针对缓冲区,Java虚拟机须要花时间生成对象,须要花时间进行垃圾回收处置。却说我,尽量重复利用缓冲区。

正例:

用反射赋值对象,主要优点是节省了代码量,主要缺点却是性能有所下降。

反例:

反例:

反例:

为了提高守护应用应用应用程序下行速率 单位,在设计上尽量使用同一缓冲区。

正例:

正例:

反例:

反例:

反例:

反例:

反例:

加进每个转化最好的依据 中的缓冲区申请,申请2个 缓冲区给每个转化最好的依据 使用。从时间上来说,节约了大量缓冲区的申请释放时间;从空间上来说,节约了大量缓冲区的临时存储空间。

正例:

反例:

相对于条件表达式,异常的处置下行速率 单位更低。

在Java集合类库中,List的contains最好的依据 普遍时间比较复杂度是O(n),而HashSet的时间比较复杂度为O(1)。肯能须要频繁调用contains最好的依据 查找数据,可不须要先将List转加进HashSet。

反例:

反例:

将集合转换为数组有2种形式:toArray(new T[n])和toArray(new T[0])。在旧的Java版本中,建议使用toArray(new T[n]),肯能创建数组时所需的反射调用非常慢。在OpenJDK6后,反射调用是内在的,使得性能得以提高,toArray(new T[0])比toArray(new T[n])下行速率 单位更高。此外,toArray(new T[n])比toArray(new T[0])多获取一次列表大小,肯能计算列表大小耗时过长,也会原因着toArray(new T[n])下行速率 单位降低。

反例:

正例:

同理,世界上不都可不可否 有你这些代码:高效代码和低效代码;世界上不都可不可否 有你这些人:编写高效代码的人和编写低效代码的人。怎样编写高效代码,是每个研发团队都面临的2个 重大什么的问题。却说我,作者根据实际经验,查阅了大量资料,总结了"Java高效代码400例",让每2个 Java守护应用应用程序员都能编写出"高效代码"。

正例:

正例:

反例:

为类指定final修饰符,可不须要让该类不可不须要被继承。肯能指定了2个 类为final,则该类所有的最好的依据 全部都是final的,Java编译器会寻找肯能内联所有的final最好的依据 。内联对于提升Java运行下行速率 单位作用重大,具体可参见Java运行期优化,可不可否 使性能平均提高400%。

正例:

Java 中的基本数据类型double、float、long、int、short、char、boolean,分别对应包装类Double、Float、Long、Integer、Short、Character、Boolean。 JVM支持基本类型与对应包装类的自动转换,被称为自动装箱和拆箱。装箱和拆箱全部都是须要CPU和内存资源的,却说我应尽量处置使用自动装箱和拆箱。

用移位操作可不须要极大地提高性能。对于乘除2^n(n为正整数)的正整数计算,可不须要用移位操作来代替。

反例:

反例:

世界上不都可不可否 有你这些物质:高下行速率 单位和低下行速率 单位;世界上不都可不可否 有你这些人:高下行速率 单位的人和低下行速率 单位的人。——萧伯纳

同步代码块是有性能开销的,肯能取舍可不须要合并为同一块儿步代码块,就应该尽量合并为同一块儿步代码块。

正例:

使用守护应用应用程序安全类,比被委托人实现的同步代码更简洁更高效。

正则表达式匹配下行速率 单位较低,尽量使用字符串匹配操作。

正例:

正例:

字符串的长度不取舍,而字符的长度固定为1,查找和匹配的下行速率 单位自然提高了。

初始化时,指定缓冲区的预期容量大小,处置多次扩容浪费时间和空间。

正例:

反例:

正例:

反例:

正例:

不可变的成员变量,着实须要支持多守护应用应用程序访问,也可不须要使用非守护应用应用程序安全类。

正例:

反例:

正例:

正例:

正例:

建议:集合应该提供2个 toArray(Class<T> clazz)最好的依据 ,处置无用的空数组初始化(new T[0])。

最好的依据 调用会引起入栈和出栈,原因着消耗更多的CPU和内存,应当尽量处置何必 要的函数封装。当然,为了使代码更简洁、更清晰、更易维护,增加一定的最好的依据 调用所带来的性能损耗是值得的。

正例:

正例:

正例:

反例:

本文是《 Java编程技巧之数据内部管理 》的姊妹篇,作者在这里却说我抛砖引玉,希望我们进行补充完善。

反例:

推荐使用System.arraycopy拷贝数组,也可不须要使用Arrays.copyOf拷贝数组。

作为一名长期奋战在业务一线的"IT民工",这麼 肯能去研究哪几种高深莫测的"理论",不都可不可否 专注于背后看得见摸得着的"技术",致力于做到"干一行、爱一行、专一行、精一行"。

正例:

最好的依据 指定final修饰符,可不须要让最好的依据 不可不须要被重写,Java编译器会寻找肯能内联所有的final最好的依据 。内联对于提升Java运行下行速率 单位作用重大,具体可参见Java运行期优化,可不可否 使性能平均提高400%。

反例:

对于列表,可分为随机访问和非随机访问两类,可不须要用算不算实现RandomAccess接口判断。随机访问列表,直接通过get获取数据不影响下行速率 单位。而非随机访问列表,通过get获取数据下行速率 单位极低。

反例:

反例:

反例:

正例:

其中,使用setLength最好的依据 让缓冲区重新从0现在结束。

正例:

反例:

协议编程,可不须要@NonNull和@Nullable标注参数,算不算遵循全凭实现者自觉。

正例:

反例:

在2个 最好的依据 中,肯能不都可不可否 一小次要的逻辑是须要同步控制的,肯能同步控制了整个最好的依据 会影响执行下行速率 单位。却说我,尽量减少同步代码块的范围,只对须要进行同步的代码进行同步。

正例:

反例:

肯能须要先判断处于再进行获取,可不须要直接获取并判断空,从而处置了二次查找操作。

正例:

当循环体抛出异常后,不让循环继续执行时,这麼 必要在循环体中捕获异常。肯能,太满的捕获异常会降低守护应用应用程序执行下行速率 单位。

正例:

正例:

在老版JDK中,建议“尽量何必 在循环体内定义变量”,怎样让 在新版的JDK中肯能做了优化。通过对编译后的字节码分析,变量定义在循环体外和循环体内这麼 本质的区别,运行下行速率 单位基本上是一样的。反而,根据“ 局部变量作用域最小化 ”原则,变量定义在循环体内更科学更便于维护,处置了延长大对象生命周期原因着延缓回收什么的问题 。

注意:使用Spring的AOP内部管理时,须要对Bean进行动态代理,肯能最好的依据 加进了final修饰,将不让被代理。

反例:

反例:

着实,不管列表支不支持随机访问,都应该使用迭代进行遍历。

正例:

正例:

正例:

JDK提供的最好的依据 可不须要一步指定集合的容量,处置多次扩容浪费时间和空间。一块儿,哪几种最好的依据 的底层也是调用System.arraycopy最好的依据 实现,进行数据的批量拷贝下行速率 单位更高。

静态最好的依据 的好处却说我不让生成类的实例就可不须要直接调用。静态最好的依据 不再属于某个对象,却说我属于它所在的类。只须要通过其类名就可不须要访问,不须要再消耗资源去反复创建对象。即便在类内部管理的私有最好的依据 ,肯能这麼 使用到类成员变量,也应该声明为静态最好的依据 。

注意:所有的private最好的依据 会隐式地被指定final修饰符,却说我何必 再为其指定final修饰符。

if-else励志的话 ,每个if条件励志的话 全部都是加装计算,直到if条件励志的话 为true为止。switch励志的话 进行了跳转优化,Java中采用tableswitch或lookupswitch指令实现,对于多常量取舍分支处置下行速率 单位更高。经过试验证明:在每个分支冒出概率相同的清况 下,低于2个分支时if-else励志的话 下行速率 单位更高,高于2个分支时switch励志的话 下行速率 单位更高。

反例:

正例:

反例:

反例:

正例:

在JDK类库的最好的依据 中,却说我最好的依据 返回值都采用了基本数据类型,首先是为了处置何必 要的装箱和拆箱,其次是为了处置返回值的空指针判断。比如:Collection.isEmpty()和Map.size()。

反例:

注意:使用Spring的AOP内部管理时,须要对Bean进行动态代理,肯能Bean类加进了final修饰,会原因着异常。

正例:

反例:

正例:

反例:

反例:

正例:

反例:

正例:

反例: