java代码大全(java常用代码大全)-j9九游会登录

导读

世界上只有两种物质:高效和低效;世界上只有两种人:高效率的人和低效率的人。——萧伯纳

同样,世界上只有两种代码:高效代码和低效代码;世界上只有两种人:写高效代码的人和写低效代码的人。如何编写高效的代码是每个r&d团队面临的主要问题。因此,笔者根据实践经验,查阅了大量资料,总结出& # 34;50例ja高效代码& # 34;,让每个ja程序员都能写& # 34;高效代码& # 34;。

1.常量&变量1.1.直接赋值常量值,禁止声明新对象

直接分配一个常数值只会创建一个指向常数值的对象引用。

反例:

龙i =新龙(1l);string s =新字符串(& # 34;abc & # 34);示例:

龙i = 1l;字符串s = & # 34abc & # 34;1.2.当成员变量的值不需要改变时,尽量将其定义为静态常量。在类的每个对象实例中,每个成员变量都有一个副本,而成员静态常量只有一个实例。

反例:

public类http connection { private final long time out = 5l;…}正面例子:

public类http connection { private static final long time out = 5l;…}1.3.尽量使用基本数据类型,避免ja中基本数据类型double、float、long、int、short、char、boolean的自动打包和解包,分别对应打包类double、float、long、integer、short、character、boolean。jvm支持基本类型和相应包装类之间的自动转换,称为自动打包和解包。打包和解包需要占用cpu和内存资源,所以要尽量避免自动打包和解包。

反例:

整数和= 0;int[]值=…;for(int value:values){ sum = value;//相当于result = integer . value of(result . int value() value);}正面例子:

int sum = 0;int[]值=…;for(int value:values){ sum = value;}1.4.如果变量的初始值将被覆盖,则不需要为变量分配初始值,作为反例:

列表& ltuserdo & gtuserlist = new arraylist & lt& gt();if(is all){ userlist = userdao . query all();} else { userlist = userdao . query active();}正面例子:

列表& ltuserdo & gt用户列表;if(is all){ userlist = userdao . query all();} else { userlist = userdao . query active();}1.5.尽量在函数中使用基本类型的临时变量。基本类型参数和临时变量存储在堆栈中,访问速度更快;对象的参数和临时变量的引用存储在栈中,内容存储在堆中,所以访问速度慢。在类中,任何类型的成员变量都存储在堆中,访问速度很慢。

反例:

公共final类累加器{私有double result = 0.0dpublic void addall(@ nonnull double[]values){ for(double value:values){ result = value;}} …}正面例子:

公共final类累加器{私有double result = 0.0dpublic void addall(@ nonnull double[]values){ double sum = 0.0d;for(double value:values){ sum = value;}结果 =总和;} …}1.6.尽量不要在循环之外定义变量。在旧版的jdk中,建议“尽量不要在循环内部定义变量”,但在新版的jdk中已经进行了优化。通过对编译后字节码的分析,循环外和循环内的变量定义没有本质区别,运行效率基本相同。相反,根据“最小化局部变量范围”的原则,循环中变量的定义更加科学,也更容易维护,从而避免了因延长大型对象的生命周期而导致的延迟回收的问题。

反例:

uservo uservo列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(user do user do:user dolist){ user vo = new user vo();user vo . setid(user do . getid());…user volist . add(user vo);}正面例子:

列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(user do user do:user dolist){ user vo user vo = new user vo();user vo . setid(user do . getid());…user volist . add(user vo);}1.7.不可变的静态常量。尽量使用非线程安全类的不可变静态常量。虽然支持多线程访问是必要的,但是也可以使用非线程安全的类。

反例:

公共静态最终地图& ltstring,class & gtclass _ map静态{ map & ltstring,class & gtclass map = new concurrent hashmap & lt;& gt(16);class map . put(& # 34;varchar & # 34,ja . lang . string . class);…class _ map = collections . unmodifiablemap(class map);}正面例子:

公共静态最终地图& ltstring,class & gtclass _ map静态{ map & ltstring,class & gtcp = new hashmap & lt& gt(16);class map . put(& # 34;varchar & # 34,ja . lang . string . class);…class _ map = collections . unmodifiablemap(class map);}1.8.不可变成员变量。尽量使用非线程安全类的不可变成员变量。虽然支持多线程访问是必要的,但是也可以使用非线程安全的类。

反例:

@servicepublic类strategyfactory实现initializing bean { @ auto wired private list & lt;策略& gt战略列表;私人地图& lt字符串,策略& gt战略地图;@ override public void afterpropertiesset(){ if(collection utils . isnotempty(strategy list)){ int size =(int)math . ceil(strategy list . size()* 4.0/3);地图& lt字符串,策略& gtmap = new concurrenthashmap & lt& gt(大小);for(strategy strategy:strategy list){ map . put(strategy . gettype(),strategy);} strategy map = collections . unmodifablemap(map);}} …}正面例子:

@servicepublic类strategyfactory实现initializing bean { @ auto wired private list & lt;策略& gt战略列表;私人地图& lt字符串,策略& gt战略地图;@ override public void afterpropertiesset(){ if(collection utils . isnotempty(strategy list)){ int size =(int)math . ceil(strategy list . size()* 4.0/3);地图& lt字符串,策略& gtmap = new hashmap & lt& gt(大小);for(strategy strategy:strategy list){ map . put(strategy . gettype(),strategy);} strategy map = collections . unmodifablemap(map);}} …}2.对象和类2.1。禁止使用json转换对象。json提供了将对象转换成json字符串,将json字符串转换成对象的功能,所以被一些人用来转换对象。虽然功能上没有问题,但是这种对象转换方式在性能上有问题。

反例:

列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuser volist = json . parse array(json . tojsonstring(user dolist),user vo . class);示例:

列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(user do user do:user dolist){ user vo user vo = new user vo();user vo . setid(user do . getid());…user volist . add(user vo);}2.2.尽量不要使用反射性的赋值对象。主要优点是节省代码量,主要缺点是性能下降。

反例:

列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(user do user do:user dolist){ user vo user vo = new user vo();bean utils . copy properties(user do,user vo);user volist . add(user vo);}正面例子:

列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(user do user do:user dolist){ user vo user vo = new user vo();user vo . setid(user do . getid());…user volist . add(user vo);}2.3.用lambda表达式替换内部匿名类对于大部分刚接触jdk8的同学来说,他们会认为lambda表达式是匿名内部类的语法糖。实际上,lambda表达式在大多数虚拟机中都是通过invokedynamic指令实现的,比匿名内部类效率更高。

反例:

列表& lt用户& gt用户列表=…;collections.sort(用户列表,新比较器& lt用户& gt(){ @ override public int compare(user user 1,user user 2){ long userid 1 = user 1 . getid();long userid 2 = user 2 . getid();…返回userid 1 . compare to(userid 2);}});示例:

列表& lt用户& gt用户列表=…;collections.sort(用户列表,(用户1,用户2)-& gt;{ long userid 1 = user 1 . getid();long userid 2 = user 2 . getid();…返回userid 1 . compare to(userid 2);});2.4.尽量避免定义不必要的子类。多一个类就需要多一个类加载,所以尽量避免定义不必要的子类。

反例:

公共静态最终地图& ltstring,class & gtclass _ map = collections . unmodifiablemap(new hashmap & lt;string,class & gt(16){ private static final long serialversionuid = 1l;{放(& # 34;varchar & # 34,ja . lang . string . class);}});示例:

公共静态最终地图& ltstring,class & gtclass _ map静态{ map & ltstring,class & gtcp = new hashmap & lt& gt(16);class map . put(& # 34;varchar & # 34,ja . lang . string . class);…class _ map = collections . unmodifiablemap(class map);}2.5.尝试指定类的最后一个修饰符。为类指定final修饰符会使该类无法被继承。如果一个类被指定为final,那么该类的所有方法都是final,ja编译器将寻找机会内联所有final方法。内联在提高ja运行效率方面起着重要的作用。详见ja运行时优化,平均可以提升50%的性能。

反例:

课程日期助手{…}正面例子:

公共类日期助手{…}注意:使用spring的aop特性时,需要动态代理bean。如果bean类用final修饰,就会导致异常。

3.方法3.1.把跟类成员变量无关的方法声明成静态方法

静态方法的优点是可以直接调用它们,而无需生成类的实例。静态方法不再属于一个对象,而是属于它所在的类。只能通过类名访问,不需要消耗资源重复创建对象。即使是类中的私有方法,如果不使用类成员变量,也应该声明为静态方法。

反例:

public int getmonth(date date){ calendar calendar = calendar . getinstance();calendar.settime(日期);返回calendar.get(calendar。月) 1;}正面例子:

public static int getmonth(date date){ calendar calendar = calendar . getinstance();calendar.settime(日期);返回calendar.get(calendar。月) 1;}3.2.尽量使用基本数据类型作为方法参数类型,避免不必要的打包、解包和空指针判断作为反例:

public static double sum(double value 1,double value 2){ double double 1 = objects . is null(value 1)?0.0d:值1;double double 2 = objects . is null(value 2)?0.0d:值2;返回double 1 double 2;}double result = sum(1.0d,2.0d);示例:

公共静态double sum(double value1,double value 2){ return value 1 value 2;}double result = sum(1.0d,2.0d);3.3.尽量使用基本数据类型作为方法返回值类型,避免不必要的装箱、拆箱和空指针判断。在jdk类库的方法中,很多方法返回值采用基本数据类型,首先是为了避免不必要的装箱和拆箱,其次是为了避免返回值的空指针判断。例如:collection.isempty()和map.size()。

反例:

public static boolean is valid(userdo user){ if(objects . is null(user)){ return false;}返回布尔值。true . equals(user . getis valid());}//调用代码userdo user =…;boolean isvalid = isvalid(用户);if(objects . nonnull(is valid)& & is valid . boolean value()){…}正面例子:

public static boolean is valid(userdo user){ if(objects . is null(user)){ return false;}返回布尔值。true . equals(user . getis valid());}//调用代码userdo user =…;if (isvalid(user)) {…}3.4.协议方法的参数值不是空,避免了不必要的空指针判断协议编程。可以用@nonnull和@nullable来标记参数,要不要遵循就看调用者的意识了。

反例:

public static boolean is valid(userdo user){ if(objects . is null(user)){ return false;}返回布尔值。true . equals(user . getis valid());}正面例子:

public static boolean is valid(@ nonnull user do user){ return boolean。true . equals(user . getis valid());}3.5.协议方法的返回值不是空。避免不必要的空指针来判断协议编程。可以用@nonnull和@nullable标记参数。是否遵循,取决于实施者的自觉。

反例:

//定义接口公共接口orderservice { public list < order vo & gt;queryuserorder(长userid);}//调用代码列表order list = orderservice . queryuseorder(userid);if(集合utils。不为空(订单列表)){for(订单:订单列表){…}}正面例子:

//定义接口公共接口orderservice { @ nonnull public list < order vo & gt;queryuserorder(长userid);}//调用代码列表order list = orderservice . queryuseorder(userid);for (order voorder:订单列表){…} 3.6.被调用的方法已经支持判断空处理,调用方法不需要再次进行判断空处理。反例:

userdo user = nullif(string utils . isnotblank(value)){ user = json . parse object(value,userdo . class);}正面例子:

userdo user = json . parse object(value,userdo . class);3.7.尽量避免不必要的函数封装方法调用,这样会造成推入和推出,造成更多的cpu和内存消耗。应尽可能避免不必要的函数封装。当然,为了让代码更简洁、更清晰、更易于维护,增加某些方法调用带来的性能损失是值得的。

反例:

//函数封装公共静态boolean is vip(boolean is vip){ return boolean . true . equals(is vip);}//使用代码boolean isvip = isvip(user . get vip());示例:

布尔型isvip =布尔型。true . equals(user . get vip());3.8.尝试指定方法的最终修饰符。方法指定最后一个修饰符,因此无法重写该方法。ja编译器将寻找内联所有最终方法的机会。内联在提高ja运行效率方面起着重要的作用。详见ja运行时优化,平均可以提升50%的性能。

注意:所有私有方法都被隐式地分配了final修饰符,所以没有必要给它们分配final修饰符。

反例:

公共矩形{…公共double area () {…}}正面例子:

公共矩形{…公共最终double area () {…}}注意:使用spring的aop特性时,需要动态代理bean。如果该方法用final修饰,它将不会被代理。

4.表达式4.1.尽量减少方法的重复调用

反例:

列表& ltuserdo & gt用户列表=…;for(int i = 0;我& ltuser list . size(); ) {…}正面例子:

列表& ltuserdo & gt用户列表=…;int user length = userlist . size();for(int i = 0;我& ltuserlength i ) {…}4.2.作为反例,尽量避免不必要的方法调用:

列表& ltuserdo & gtuserlist = userdao . query active();if(is all){ userlist = userdao . query all();}正面例子:

列表& ltuserdo & gt用户列表;if(is all){ userlist = userdao . query all();} else { userlist = userdao . query active();}4.3.尽量用移位代替正整数的乘除。使用移位操作可以大大提高性能。对于2 n (n为正整数)乘除正整数的计算,可以用移位运算代替。

反例:

int num 1 = a * 4;int num 2 = a/4;示例:

int num1 = a & lt& lt2;int num2 = a & gt& gt2;4.4.提取公共表达式,避免重复计算,提取公共表达式,只计算一次值,然后重用值。

反例:

双距离= math . sqrt((x2-x1)*(x2-x1) (y2-y1)*(y2-y1));示例:

double dx = x2-x1;double dy = y2-y1;double distance = math . sqrt(dx * dx dy * dy);或者双距离= math.sqrt (math.power (x2-x1,2) math.power (y2-y1,2));4.5.尽量不要在条件表达式中使用!反向使用!反算会再做一次,不需要的话会优化。

反例:

如果(!(a & gt= 10)) {…//条件处理1}否则{…//条件处理2}正例:

如果(a & lt10) {…//条件处理1}否则{…//条件处理2}4.6。对于多常量选择分支,尽量使用switch语句,而不是if-else语句if-else语句。每个if条件语句都应该被额外计算,直到if条件语句为真。switch语句通过跳转进行优化,在ja中通过tableswitch或lookupswitch指令实现,对于选择多个常量的分支效率更高。实验表明,if-else语句在每个分支的概率相同时效率更高,switch语句在低于5个分支时效率更高。

反例:

if (i == 1) {…;//branch 1} else if (i == 2) {…;//branch 2} else if (i ==…) {…;//branch n} else {…;//分支n 1}正例:

开关(i){情况1:…//分支1中断;2:案例…//分支2断开;情况…:…//branch n break;默认值:…//分支n 1 break;}备注:如果业务复杂,可以采用map实现策略模式。

5.字符串5.1.尽量不要使用正则表达式匹配

正则表达式匹配效率低,尽量用字符串匹配。

反例:

字符串源= & # 34;a::1,b::2,c::3,d::4 & # 34;;string target = source . replace all(& # 34;::", "=");stringp[]targets = source . spit(& # 34;::");示例:

字符串源= & # 34;a::1,b::2,c::3,d::4 & # 34;;string target = source . replace(& # 34;::", "=");stringp[]targets = string utils . split(source,& # 34;::");5.2.尝试用字符替换字符串。字符串的长度是不确定的,而字符的长度固定为1,搜索匹配的效率自然提高。

反例:

字符串源= & # 34;甲:1,乙:2,丙:3,丁:4 & # 34;;int index = source . index of(& # 34;:");string target = source . replace(& # 34;:", "=");示例:

字符串源= & # 34;甲:1,乙:2,丙:3,丁:4 & # 34;;int index = source . index of(& # 39;:');string target = source . replace(& # 39;:', '=');5.3.尽量使用stringbuilder进行字符串拼接。string是final类,其内容不可修改,所以每次字符串拼接都会生成一个新的对象。stringbuilder在初始化时申请了一块内存,以后所有的字符串拼接都将在这块内存中进行,不需要申请新的内存和生成新的对象。

反例:

字符串s = & # 34";for(int i = 0;我& lt10;i ) { if (i!= 0){ s = & # 39;,';} s = i;}正面例子:

stringbuilder = new stringbuilder(128);for(int i = 0;我& lt10;i ) { if (i!= 0){ . append(& # 39;,');} .append(一);}5.4.不要使用& # 34;" 使用& # 34;" 字符串转换,好用但效率低,推荐用string.valueof。

反例:

int i = 12345字符串s = & # 34" i;示例:

int i = 12345string s = string . value of(i);6.数组6.1。不要使用循环复制数组,尽量使用system.arraycopy数组。建议使用system.arraycopy array或arrays.copyof array。

反例:

int[] sources = new int[] {1,2,3,4,5 };int[]targets = new int[sources . length];for(int i = 0;我& lt目标.长度;i ){ targets[i]= sources[i];}正面例子:

int[] sources = new int[] {1,2,3,4,5 };int[]targets = new int[sources . length];system.arraycopy(源,0,目标,0,目标.长度);6.2.当一个集合被转换为t类型数组时,尝试传入空数组t[0]。将集合转换为数组有两种形式:toarray(new t[n])和toarray(new t[0])。在旧的ja版本中,建议使用toarray(new t[n]),因为创建数组所需的反射调用非常慢。打开jdk 6后,反射调用是固有的,提高了性能。toarray(new t[0])比toarray(new t[n])更高效。另外,toarray(new t[n])获得列表大小的次数比toarray(new t[0])多一次,如果计算列表大小的时间太长,toarray(new t[n])的效率也会降低。

反例:

列表& lt整数& gtintegerlist = arrays.aslist(1,2,3,4,5,…);integer[]integers = integer list . to array(new integer[integer list . size()]);示例:

列表& lt整数& gtintegerlist = arrays.aslist(1,2,3,4,5,…);integer[]integers = integer list . to array(new integer[0]);//不要使用new integer[]{}建议:集合应该提供一个to array(class < t & gt;clazz)方法避免无用的空数组初始化(新t[0])。

6.3.集合转化为object数组时,尽量使用toarray()方法

转换对象数组时不需要使用toarray [newobject [0]],可以直接使用toarray()。避免了类型判断,也避免了空数组的应用,所以效率会更高。

反例:

列表& ltobject & gtobjectlist = arrays.aslist(1,& # 34;2", 3, "4", 5, …);object[]objects = object list . to array(new object[0]);示例:

列表& ltobject & gtobjectlist = arrays.aslist(1,& # 34;2", 3, "4", 5, …);object[]objects = object list . to array();7.设置7.1。初始化集合时,尝试指定集合大小。ja集合在初始化时会指定一个默认大小。当默认大小不再满足数据要求时,它将被扩展。每次扩展的时间复杂度可以是o(n)。因此,通过尽可能指定预测的集合大小,可以避免或减少集合的扩展时间。

反例:

列表& ltuserdo & gt用户列表=…;设置& ltlong & gtuserset = new hashset & lt& gt();地图& ltlong,userdo & gtusermap = new hashmap & lt& gt();列表& ltuservo & gtuserlist = new arraylist & lt& gt();for(userdo userdo:userdolist){ userset . add(userdo . getid());usermap.put(userdo.getid(),userdo);userlist . add(transuser(userdo));}正面例子:

列表& ltuserdo & gt用户列表=…;int usersize = user dolist . size();设置& ltlong & gtuserset = new hashset & lt& gt(usersize);地图& ltlong,userdo & gtusermap = new hashmap & lt& gt((int)math . ceil(usersize * 4.0/3));列表& ltuservo & gtuserlist = new arraylist & lt& gt(usersize);for(userdo userdo:userdolist){ userset . add(userdo . getid());usermap.put(userdo.getid(),userdo);userlist . add(transuser(userdo));}7.2.不要循环复制集合,尝试使用jdk提供的方法复制集合。jdk提供的方法可以一步指定集合的容量,避免多次扩展浪费时间和空。同时,这些方法的底层也是通过调用system.arraycopy方法来实现的,使得批量复制数据的效率更高。

反例:

列表& ltuserdo & gt用户1列表=…;列表& ltuserdo & gt用户2列表=…;列表& ltuserdo & gtuserlist = new arraylist & lt& gt(user 1 list . size() user 2 list . size());for(userdo user 1:user 1 list){ userlist . add(user 1);} for(userdo user 2:user 2 list){ userlist . add(user 2);}正面例子:

列表& ltuserdo & gt用户1列表=…;列表& ltuserdo & gt用户2列表=…;列表& ltuserdo & gtuserlist = new arraylist & lt& gt(user 1 list . size() user 2 list . size());userlist . addall(user 1 list);userlist . addall(user 2 list);7.3.尝试使用arrays.aslist将数组转换为列表。原理和& # 34;不要循环复制集合,尽量使用jdk提供的方法复制集合& # 34;类似。

反例:

列表& lt字符串& gttypelist = new arraylist & lt& gt(8);type list . add(& # 34;short & # 34);type list . add(& # 34;整数& # 34;);type list . add(& # 34;龙& # 34;);字符串[]名称=…;列表& lt字符串& gt名称列表=…;for(string name:names){ name list . add(name);}正面例子:

列表& lt字符串& gttypelist = arrays . aslist(& # 34;short & # 34, "整数& # 34;, "龙& # 34;);字符串[]名称=…;列表& lt字符串& gt名称列表=…;name list . addall(arrays . as list(names));7.4.直接迭代要使用的集合。直接迭代要使用的集合,不需要通过其他操作获取数据。

反例:

地图& ltlong,userdo & gt用户地图=…;for(long userid:user map . keyset()){ userdo user = user map . get(userid);…}正面例子:

地图& ltlong,userdo & gt用户地图=…;对于(图。entry & ltlong,userdo & gtuser entry:user map . entry set()){ long userid = user entry . getkey();userdo user = user entry . getvalue();…}7.5.不要用size方法检测空,必须用isempty方法检测空。使用size方法检测空没有逻辑问题,但是使用isempty方法使得代码可读性更好,可以获得更好的性能。任何isempty方法的时间复杂度都是o(1),但某些size方法的时间复杂度可能是o(n)。

反例:

列表& ltuserdo & gt用户列表=…;if (userlist.size() == 0) {…}地图& ltlong,userdo & gt用户地图=…;if (usermap.size() == 0) {…}正面例子:

列表& ltuserdo & gt用户列表=…;if (userlist.isempty()) {…}地图& ltlong,userdo & gt用户地图=…;if (usermap.isempty()) {…}7.6.用非randomaccess列表,尽量用迭代代替随机访问。对于列表,可以分为随机访问和非随机访问,可以通过随机访问接口是否实现来判断。随机访问列表,直接通过get获取数据不影响效率。而不是随机访问列表,通过get获取数据效率极低。

反例:

linkedlist & ltuserdo & gt用户列表=…;int size = userdolist . size();for(int i = 0;我& lt尺寸;i ){ userdo userdo = userdolist . get(i);…}正面例子:

linkedlist & ltuserdo & gt用户列表=…;for (userdo userdo: userdolist) {…}其实不管列表分支是否支持随机访问,都应该迭代。

7.7.尽量使用hashset判断值存在

在ja集合类库中,list的contains方法的时间复杂度一般为o(n),而hashset的时间复杂度为o(1)。如果需要经常调用contains方法来查找数据,可以先将list转换成hashset。

反例:

列表& ltlong & gtadminidlist =…;列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(userdo userdo:userdolist){ if(adminidlist . contains(userdo . getid()){ uservolist . add(trans user(userdo));}}正面例子:

设置& ltlong & gtadminidset =…;列表& ltuserdo & gt用户列表=…;列表& ltuservo & gtuservolist = new arraylist & lt& gt(userdolist . size());for(userdo userdo:userdolist){ if(adminid set . contains(userdo . getid()){ uservolist . add(trans user(userdo));}}7.8.避免在获得之前判断存在。如果在获取之前需要判断存在,可以直接获取并判断空,从而避免第二次搜索操作。

反例:

公共静态uservo transuser(userdo用户,map & ltlong,roledo & gtrole map){ user vo user vo = new user vo();user vo . setid(user . getid());…if(role map . contains(user . getroleid()){ roledo role = role map . get(user . getroleid());user vo . set role(trans role(role));}}正面例子:

公共静态uservo transuser(userdo用户,map & ltlong,roledo & gtrole map){ user vo user vo = new user vo();user vo . setid(user . getid());…roledo role = role map . get(user . getroleid());if(objects . nonnull(role)){ user vo . set role(trans role(role));}}8.例外8.1。直接捕捉对应的异常,避免通过instanceof判断,代码更加高效简洁。

反例:

请尝试{ sedata();} catch(exception e){ if(e instance of io exception){ log . error(& # 34;保存数据io时出现异常& # 34;,e);} else { log . error(& # 34;保存数据时的其他异常& # 34;,e);}}正面例子:

请尝试{ sedata();} catch(io exception e){ log . error(& # 34;保存数据io时出现异常& # 34;,e);} catch(exception e){ log . error(& # 34;保存数据时的其他异常& # 34;,e);}8.2.尽量避免在循环中捕捉异常。当循环体抛出异常时,当循环不需要继续执行时,没有必要在循环体中捕捉异常。因为异常太多会降低程序执行的效率。

反例:

公共双和(列表& lt字符串& gtvalue list){ double sum = 0.0d;for(string value:valuelist){ try { sum = double . parse double(value);} catch(numberformatexception e){ return null;} }返回sum}正面例子:

公共双和(列表& lt字符串& gtvalue list){ double sum = 0.0d;try { for(string value:valuelist){ sum = double . parse double(value);} } catch(numberformatexception e){ return null;}返回sum}8.3.禁止使用异常来控制业务流程。与条件表达式相比,异常处理效率较低。

反例:

public static boolean is valid(userdo user){ try { return boolean。true . equals(user . getis valid());} catch(nullpointerexception e){ return false;}}正面例子:

public static boolean is valid(userdo user){ if(objects . is null(user)){ return false;}返回布尔值。true . equals(user . getis valid());}9.缓冲器9.1。初始化时,尽可能指定缓冲区大小。初始化时,指定缓冲区的预期容量,以避免多次扩展浪费时间和空。

反例:

string buffer buffer = new string buffer();stringbuilder builder = new stringbuilder();示例:

string buffer buffer = new string buffer(1024);stringbuilder builder = new stringbuilder(1024);9.2.尽可能重复使用同一个缓冲区。对于缓冲区,ja虚拟机需要花时间生成对象,也需要花时间进行垃圾收集。因此,尽量重复使用缓冲区。

反例:

stringbuilder builder 1 = new stringbuilder(128);builder 1 . append(& # 34;update t _ user set name = & # 39").追加(用户名)。追加(& # 34;'其中id = & # 34).append(userid);statement . execute update(builder 1 . tostring());stringbuilder builder 2 = new stringbuilder(128);builder 2 . append(& # 34;select id,name from t_user其中id = & # 34).append(userid);resultset resultset =语句. execute query(builder 2 . tostring());…正面例子:

stringbuilder builder = new stringbuilder(128);builder . append(& # 34;update t _ user set name = & # 39").追加(用户名)。追加(& # 34;'其中id = & # 34).append(userid);statement . execute update(builder . tostring());builder . setlength(0);builder . append(& # 34;select id,name from t_user其中id = & # 34).append(userid);resultset resultset =语句. execute query(builder . tostring());…其中setlength方法用于从0重新启动缓冲区。

9.3.尽量设计使用同一缓冲区

为了提高程序的运行效率,在设计中尽量使用相同的缓冲区。

反例:

//将xml (userdo)公共静态字符串转换为xml(user douser){ string builder = newstring builder(128);builder . append(& # 34;& ltuserdo & gt");builder . append(to xml(user . getid()));builder . append(to xml(user . getname()));builder . append(to xml(user . getrole()));builder . append(& # 34;& lt/userdo & gt;");返回builder . tostring();}//将xml (long)公共静态字符串转换为xml(long value){ stringbuilder = new stringbuilder(128);builder . append(& # 34;& ltlong & gt");builder.append(值);builder . append(& # 34;& lt/long & gt;");返回builder . tostring();} …//使用代码userdo user =…;string xml = toxml(用户);示例:

//将xml (userdo) public static void转换为xml (stringbuilder,user douser){ builder . append(& # 34;& ltuserdo & gt");toxml(builder,user . getid());toxml(builder,user . getname());toxml(builder,user . getrole());builder . append(& # 34;& lt/userdo & gt;");}//将xml (long) public static void转换为xml (stringbuilder,long value){ builder . append(& # 34;& ltlong & gt");builder.append(值);builder . append(& # 34;& lt/long & gt;");} …//使用代码userdo user =…;stringbuilder builder = new stringbuilder(1024);toxml(构建者,使用者);string xml = builder . tostring();删除每个转换方法中的缓冲区应用程序,并为每个转换方法申请一个缓冲区。时间上,节省了大量缓冲区的应用发布时间;从空室,节省了大量的暂存空室的缓冲区。

9.4.尽量使用缓冲流减少io操作

使用缓冲流bufferedreader、bufferedwriter、bufferedinputstream、bufferedoutputstream等。可以大大减少io次数,提高io速度。

反例:

try(file inputstream input = new file inputstream(& # 34;一& # 34;);file output stream output = new file output stream(& # 34;b & # 34)){ int size = 0;byte[] temp =新字节[1024];while ((size = input.read(temp))!= -1) { output.write(temp,0,size);} } catch(io exception e){ log . error(& # 34;复制文件时出现异常& # 34;,e);}正面例子:

try(bufferedinputstream input = new bufferedinputstream(new file inputstream(& # 34;一& # 34;));bufferedoutputstream output = new bufferedoutputstream(new file output stream(& # 34;b & # 34))){ int size = 0;byte[] temp =新字节[1024];while ((size = input.read(temp))!= -1) { output.write(temp,0,size);} } catch(io exception e){ log . error(& # 34;复制文件时出现异常& # 34;,e);}其中,可以根据实际情况手动指定缓冲流的大小,最大化缓冲流的缓冲效果。

10.线程10.1.在单线程中,尽量使用非线程安全类

使用非线程安全的类可以避免不必要的同步开销。

反例:

string buffer buffer = new string buffer(128);buffer . append(& # 34;select * from & # 34).append(t_user)。追加(& # 34;其中id =?");示例:

stringbuilder buffer = new stringbuilder(128);buffer . append(& # 34;select * from & # 34).append(t_user)。追加(& # 34;其中id =?");0.2.多线程中,尽量使用线程安全类,比自己实现的同步代码更简洁高效。

反例:

private volatile int计数器= 0;public void access(long userid){ synchronized(this){ counter ;} …}正面例子:

private final atomic integer counter = new atomic integer(0);public void access(long userid){ counter . incrementandget();..}10.3.最小化同步代码块的范围。在一个方法中,可能只有一小部分逻辑需要同步,如果整个方法都同步,会影响执行效率。所以尽量缩小同步代码块的范围,只同步需要同步的代码。

反例:

private volatile int计数器= 0;公共同步void访问(长userid){ counter ;…//异步操作}正例:

private volatile int计数器= 0;public void access(long userid){ synchronized(this){ counter ;} …//异步操作}10.4。尝试合并到同一个同步代码块中会有性能开销。如果确定可以合并到同一个同步码块中,就尽可能合并到同一个同步码块中。

反例:

//处理单一订单公共同步处理订单(orderdo order) {…}//处理所有订单公共void handle order(list & lt < orderdo & gt;order list){ for(order do order:order list){ handle order(order);}}正面例子:

//处理单一订单公共处理订单(orderdo order) {…}//处理所有订单公共同步void句柄订单(list < orderdo & gtorder list){ for(order do order:order list){ handle order(order);}}10.5.尝试使用线程池来减少线程开销。多线程中两个必要的开销:线程创建和上下文切换。通过使用线程池,可以尽可能地避免这些开销。

反例:

public void execute task(runnable runnable){ new thread(runnable)。start();}正面例子:

private static final executorservice executor _ service = executors . newfixedthreadpool(10);public void execute task(runnable runnable){ executorservice . execute(runnable);}

后记

作为一个长期战斗在商业第一线的人& # 34;it民工& # 34;,没有机会研究什么深奥的东西& # 34;理论& # 34;,只能关注j9九游会 面前看得见摸得着的东西& # 34;技术& # 34;,致力于做& # 34;做好一份工作,热爱一份工作,专攻一份工作& # 34;。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文链接:https://www.andon8.com/197027.html

网站地图