当前位置: 首页 > 科技观察

改进Java代码的八个建议

时间:2023-03-23 01:21:46 科技观察

前言Java是一门优秀的面向对象编程语言。同一个问题有多种解决方案,但究竟哪种实现方式是最优的或接近最优的,还需要不断探索JDK的底层原理。本文提出了一些改进Java的小建议。希望能在您平时的开发实践中为您提供一些小小的帮助。用整数处理货币考虑下面代码输出的值?publicstaticvoidmain(String[]args){System.out.println(10.00-9.60);}实际结果:0.40000000000000036原因:由于浮点数的存储规则,计算机中的浮点数可能不准确电脑里的数字。0.4的二进制值为:0.0110...乘以2并依次排列解决方法:使用BigDecimal使用整数(将运算涉及的值扩大100倍,转为整数,再减100显示时的次数,这样的优点是计算简单准确,一般用于非金融行业(如零售行业)。根据国际标准IEEE(电气和电子工程协会),任何浮点数的二进制数NUM可以写成:NUM=(-1)^S*M*2^E;//(S表示符号,E表示阶乘,M表示有效数)①当S为0时,表示正数;当S为1时表示负数②M表示有效数,1<=M<2③2^E表示指数,如十进制为3.0,二进制为0011.0可写为(-1)^0*1.1*2^1。比如十进制的-3.0,二进制的-0011.0可以写成(-1)^1*1.1*2^1,同时指定float类型有一个符号位(S)、8个指数位(E)和23个有效位(M),double类型有一个符号位(S)、11个指数(E)和52个有效数字(M)边界值检查publicclassDemo{//成员拥有的最大产品数量publicfinalstaticintLIMIT=2000;publicstaticvoidmain(String[]args){//会员当前使用的产品数量intcur=1000;扫描仪输入=新扫描仪(System.in);System.out.println("请输入订购数量:");while(input.hasNextInt()){intorder=input.nextInt();if(order>0&&order+cur<=LIMIT){System.out.println("您已成功订购:"+order+"products");}else{System.out.println("超出配额,预约失败!");}}}}原因:数字越界导致验证条件无效。输入一个边界值2147483647建议:如果一个方法接收一个int类型的参数,必须测试以下三个值:0,positive,maximum,negative,minimum,其中positivemaximum,negativeminimum是边界值当心null包装器类型的值publicstaticinttestMethod(Listlist){intcount=0;for(inti:list){count+=i;}返回计数;}publicstaticvoidmain(String[]args){Listlist=newArrayList();列表.添加(1);列表.添加(2);列表.添加(空);System.out.println(测试方法(列表));}原因:在程序的for循环中,隐含了一个拆箱过程。在此过程中,包装类型转换为基本类型。我们知道,拆箱过程是通过调用包装对象的intValue方法实现的。因为封装类型如果为null,访问其intValue方法时难免会报空指针异常。解决方法:添加Null校验。要使用偶数判断代替奇数判断,你需要了解Java中余数算法的实现以及后者的任何编程语言。可以参考编程语言中余数是如何实现的。publicstaticvoidmain(String[]args){扫描器输入=newScanner(System.in);System.out.println("请输入多个数判断奇偶数:");while(input.hasNextLine()){inti=input.nextInt();Stringstr=i+"->"+(i%2==0?"even":"odd");//Stringstr=i+"->"+(i%2==1?"奇数":"偶数");System.out.println(str);}}谨慎包装类型大小比较publicstaticvoidmain(String[]args){Integeri=newInteger(100);整数j=新整数(100);比较(我,j);}publicstaticvoidcompare(Integeri,Integerj){System.out.println(i==j);System.out.println(i>j);System.out.println(ij和i”和“<”用来判断两个数字类型之间的大小关系。注意只能通过数字类型来判断。对于Integer包装类型,是根据其intValue()方法的返回值(即其对应的基本类型)进行比较(其他包装类型根据对应的值进行比较,如doubleValue、floatValue等.),很明显两者不能有大小关系。解决方法:问题很明确,修改总是比较容易的,直接使用Integer实例的compareTo方法即可,不过出现这种问题应该说是习惯问题,只要是比较两个对象,对应的方法应该使用方法,而不是通过Java的默认机制,除非你确定你非常了解。优先使用整数池publicstaticvoidmain(String[]args){Scannerinput=newScanner(System.in);while(input.hasNextInt()){inttempInt=input.nextInt();System.out.println("\n====="+tempInt+"相等判断=====");//newInteger生成的两个对象i=newInteger(tempInt);整数j=新整数(tempInt);System.out.println("新对象:"+(i==j));//比较i=tempInt;j=临时工;System.out.println("类型转换的基本对象:"+(i==j));//通过静态方法生成实例i=Integer.valueOf(tempInt);j=Integer.valueOf(tempInt);System.out.println("生成对象的值:"+(i==j));}}现象:大于127的数和128与555的比较不是同一个对象。解释:127的包装对象直接从整数池中获取。无论输入多少次127,得到的对象都是一样的,地址自然是相等的。但是128和555超出了整数池的范围,需要通过new生成一个新的对象。地址不同,当然也不相等。整数池的好处:提高系统性能,也节省内存空间。首选基本类型。公共类Demo7{publicstaticvoidmain(String[]args){Demo7c=newDemo7();诠释我=140;//分别传递int类型和Integer类型c.testMethod(i);c.testMethod(新整数(i));}publicvoidtestMethod(longa){System.out.println("调用了基本类型的方法");}publicvoidtestMethod(Longa){System.out.println("调用了wrapper类型的方法");}}原理:使用包装类型确实有方便的方法,但是也会造成一些不必要的混淆,比如我们这个例子中,如果testMethod()的两个重载方法都使用了基本类型,实际参数也是基本的类型,就不会出现上述问题,程序的可读性会更好。自动装箱(拆箱)很方便,但它带来的问题太多,我们甚至不知道执行的是哪个方法。其他建议:如果需要使用高效的包装类集合,提倡使用fastutil。Maven坐标:it.unimi.dsifastutil8.5.8不要随机设置randomseeds的种子随机数是固定的。在Java中,随机数的产生依赖于种子。随机数和种子之间的关系遵循以下两个原则:不同的种子产生不同的随机数。种子是相同的,即使实例不同。同一个随机数看完了上面的两条规则,我们再来看下面的例子。publicstaticvoidmain(String[]args){//随机r=newRandom();Randomr=newRandom(1000);//生成随机数的种子是固定的for(inti=1;i<=4;i++){System.out.println("th"+i+"time:"+r.nextInt());你会发现问题出在带参数的构造上,Random类(无参构造)的默认种子是System.nonoTime()的返回值(JDK1.5之前的默认种子是System.currentTimeMillis()),注意这个值是从固定时间点算起的纳秒数,不同的操作系统和硬件有不同的固定时间点,也就是说不同的操作系统有不同的纳秒值,以及同一个操作系统,纳秒值不同,随机数自然不同。顺便说一句,系统。nonoTime不能用于计算日期,因为“固定”时间是不确定的,纳秒值甚至可能是负数,这一点与System.currentTiemMillis不同。newRandom(1000)显示随机种子设置为1000,并运行多次。虽然实例不同,但是会得到相同的四个随机数。因此,除非必要,否则不要设置随机种子。结束语本文简要介绍了一些在实际开发中经常使用的改进Java代码的技巧或规范。Java中类似的知识点还有很多很多,所以要不断学习,不断成长。

最新推荐
猜你喜欢