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

  • 时间:
  • 浏览:3

正例:

if-else得话,每个if条件得话都是加装计算,直到if条件得话为true为止。switch得话进行了跳转优化,Java中采用tableswitch或lookupswitch指令实现,对于多常量挑选分支补救传输时延更高。经过试验证明:在每个分支经常出现概率相同的情况报告下,低于1个分支时if-else得话传输时延更高,高于1个分支时switch得话传输时延更高。

反例:

String是final类,内容不可修改,很多 每次字符串拼接总要生成有有1个 新对象。StringBuilder在初始化时申请了一块内存,刚刚的字符串拼接都是这块内存中执行,前会申请新内存和中成新对象。

使用size辦法 来检测空逻辑上如此大问题,但使用isEmpty辦法 使得代码更易读,否则还需用获得更好的性能。任何isEmpty辦法 实现的时间繁杂度都是O(1),否则一点size辦法 实现的时间繁杂度有不可能 是O(n)。

静态辦法 的好处很多 我前会生成类的实例就还需用直接调用。静态辦法 不再属于某个对象,很多 我属于它所在的类。只需用通过其类名就还需用访问,不需用再消耗资源去反复创建对象。即便在类结构的私有辦法 ,不可能 如此使用到类成员变量,也应该声明为静态辦法 。

原理与"无须使用循环拷贝集合,尽量使用JDK提供的辦法 拷贝集合"例如。

对于大多数刚接触JDK8的同学来说,总要认为Lambda表达式很多 我匿名结构类的语法糖。实际上, Lambda表达式在大多数虚拟机中采用invokeDynamic指令实现,相对于匿名结构类在传输时延上会更高一点。

反例:

反例:

正例:

其中,使用setLength辦法 让缓冲区重新从0开始英语 。

正例:

反例:

多进程中有有1个 必要的开销:进程的创建和上下文切换。采用进程池,还需用尽量地补救哪几个开销。

正例:

反例:

正例:

正例:

使用进程安全类,比我本人实现的同步代码更简洁更高效。

JDK提供的辦法 还需用一步指定集合的容量,补救多次扩容浪费时间和空间。并肩,哪几个辦法 的底层也是调用System.arraycopy辦法 实现,进行数据的批量拷贝传输时延更高。

反例:

反例:

正例:

正例:

协议编程,还需用@NonNull和@Nullable标注参数,是是是否是是遵循全凭实现者自觉。

反例:

直接赋值常量值,很多 我创建了有有1个 对象引用,而例如对象引用指向常量值。

反例:

反例:

反例:

正例:

反例:

其中,还需用根据实际情况报告手动指定缓冲流的大小,把缓冲流的缓冲作用发挥到最大。

辦法 调用会引起入栈和出栈,原因分析分析 消耗更多的CPU和内存,应当尽量补救前会用的函数封装。当然,为了使代码更简洁、更清晰、更易维护,增加一定的辦法 调用所带来的性能损耗是值得的。

在有有1个 辦法 中,不可能 只能一小偏离 的逻辑是需用同步控制的,不可能 同步控制了整个辦法 会影响执行传输时延。很多 ,尽量减少同步代码块的范围,只对需用进行同步的代码进行同步。

正例:

正例:

反例:

正则表达式匹配传输时延较低,尽量使用字符串匹配操作。

反例:

将集合转换为数组有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])传输时延降低。

正例:

反例:

协议编程,还需用@NonNull和@Nullable标注参数,是是是否是是遵循全凭调用者自觉。

正例:

正例:

反例:

使用非进程安全类,补救了前会用的同步开销。

转化Object数组时,如此必要使用toArray[new Object[0]],还需用直接使用toArray()。补救了类型的判断,也补救了空数组的申请,很多 传输时延会更高。

反例:

反例:

正例:

反例:

正例:

反例:

正例:

备注:不可能 业务繁杂,还需用采用Map实现策略模式。

正例:

反例:

正例:

加带每个转化辦法 中的缓冲区申请,申请有有1个 缓冲区给每个转化辦法 使用。从时间上来说,节约了一定量缓冲区的申请释放时间;从空间上来说,节约了一定量缓冲区的临时存储空间。

正例:

反例:

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

为类指定final修饰符,还需用让该类不还需用被继承。不可能 指定了有有1个 类为final,则该类所有的辦法 都是final的,Java编译器会寻找不可能 内联所有的final辦法 。内联对于提升Java运行传输时延作用重大,具体可参见Java运行期优化,利于使性能平均提高500%。

注意:使用Spring的AOP行态时,需用对Bean进行动态代理,不可能 辦法 加带了final修饰,将前会被代理。

正例:

字符串的长度不挑选,而字符的长度固定为1,查找和匹配的传输时延自然提高了。

正例:

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

不可变的静态常量,觉得 需用支持多进程访问,也还需用使用非进程安全类。

反例:

正例:

正例:

正例:

正例:

在老版JDK中,建议“尽量无须在循环体内定义变量”,否则在新版的JDK中不可能 做了优化。通过对编译后的字节码分析,变量定义在循环体外和循环体内如此本质的区别,运行传输时延基本上是一样的。反而,根据“ 局部变量作用域最小化 ”原则,变量定义在循环体内更科学更便于维护,补救了延长大对象生命周期原因分析分析 延缓回收大问题 。

正例:

相对于条件表达式,异常的补救传输时延更低。

注意:使用Spring的AOP行态时,需用对Bean进行动态代理,不可能 Bean类加带了final修饰,会原因分析分析 异常。

反例:

正例:

正例:

反例:

不可变的成员变量,觉得 需用支持多进程访问,也还需用使用非进程安全类。

反例:

反例:

反例:

反例:

正例:

同步代码块是有性能开销的,不可能 挑选还需用合并为同并肩步代码块,就应该尽量合并为同并肩步代码块。

多有有1个 类就需用多一份类加载,很多 尽量补救定义前会用的子类。

为了提高进程运行传输时延,在设计上尽量使用同一缓冲区。

正例:

注意:所有的private辦法 会隐式地被指定final修饰符,很多 无须再为其指定final修饰符。

正例:

正例:

反例:

在类的每个对象实例中,每个成员变量都是一份副本,而成员静态常量只能一份实例。

辦法 指定final修饰符,还需用让辦法 不还需用被重写,Java编译器会寻找不可能 内联所有的final辦法 。内联对于提升Java运行传输时延作用重大,具体可参见Java运行期优化,利于使性能平均提高500%。

Java集合初始化时总要指定有有1个 默认大小,当默认大小不再满足数据需求时就会扩容,每次扩容的时间繁杂度有不可能 是O(n)。很多 ,尽量指定预知的集合大小,就能补救或减少集合的扩容次数。

正例:

反例:

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

反例:

反例:

正例:

正例:

使用缓冲流BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream等,还需用大幅减少IO次数并提升IO传输时延。

正例:

正例:

直接迭代需用使用的集合,前会通过其它操作获取数据。

反例:

正例:

正例:

正例:

使用!取反会多一次计算,不可能 如此必要则优化掉。

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

JSON提供把对象转化为JSON字符串、把JSON字符串转为对象的功能,于是被一点人用来转化对象。例如对象转化辦法 ,觉得 在功能上如此大问题,否则在性能上却占据 大问题。

正例:

反例:

正例:

使用""+进行字符串转化,使用方便否则传输时延低,建议使用String.valueOf.

正例:

反例:

针对缓冲区,Java虚拟机需用花时间生成对象,需用花时间进行垃圾回收补救。很多 ,尽量重复利用缓冲区。

反例:

提取公共表达式,只计算一次值,否则重复利用值。

反例:

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

当循环体抛出异常后,前会循环继续执行时,如此必要在循环体中捕获异常。不可能 ,很多的捕获异常会降低进程执行传输时延。

世界上只能一种物质:高传输时延和低传输时延;世界上只能一种人:高传输时延的人和低传输时延的人。——萧伯纳

反例:

正例:

反例:

反例:

反例:

正例:

作为一名长期奋战在业务一线的"IT民工",如此不可能 去研究哪几个高深莫测的"理论",只能专注于身旁看得见摸得着的"技术",致力于做到"干一行、爱一行、专一行、精一行"。

反例:

反例:

在函数内,基本类型的参数和临时变量都保占据 栈(Stack)中,访问传输时延较快;对象类型的参数和临时变量的引用都保占据 栈(Stack)中,内容都保占据 堆(Heap)中,访问传输时延较慢。在类中,任何类型的成员变量都保占据 堆(Heap)中,访问传输时延较慢。

反例:

在JDK类库的辦法 中,很多 辦法 返回值都采用了基本数据类型,首先是为了补救前会用的装箱和拆箱,其次是为了补救返回值的空指针判断。比如:Collection.isEmpty()和Map.size()。

正例:

同理,世界上只能一种代码:高效代码和低效代码;世界上只能一种人:编写高效代码的人和编写低效代码的人。怎样编写高效代码,是每个研发团队都面临的有有1个 重大大问题。很多 ,作者根据实际经验,查阅了一定量资料,总结了"Java高效代码500例",让每有有1个 Java进程员都能编写出"高效代码"。

不可能 需用先判断占据 再进行获取,还需用直接获取并判断空,从而补救了二次查找操作。

反例:

反例:

在Java集合类库中,List的contains辦法 普遍时间繁杂度是O(n),而HashSet的时间繁杂度为O(1)。不可能 需用频繁调用contains辦法 查找数据,还需用先将List转加带HashSet。

推荐使用System.arraycopy拷贝数组,也还需用使用Arrays.copyOf拷贝数组。

建议:集合应该提供有有1个 toArray(Class<T> clazz)辦法 ,补救无用的空数组初始化(new T[0])。

反例:

正例:

正例:

本文是《 Java编程技巧之数据行态 》的姊妹篇,作者在这里很多 我抛砖引玉,希望村里人 儿进行补充完善。

正例:

正例:

反例:

正例:

对于列表,可分为随机访问和非随机访问两类,还需用用是是是否是是实现RandomAccess接口判断。随机访问列表,直接通过get获取数据不影响传输时延。而非随机访问列表,通过get获取数据传输时延极低。

反例:

直接捕获对应的异常,补救用instanceof判断,传输时延更高代码更简洁。

反例:

反例:

反例:

正例:

反例:

正例: