编写Java程序时要注意的一些问题

1.for循环执行效率问题

在写for循环时,注意循环的终结条件应避免多次访问统一变量 ,例如

int a[] = new int [10];

for(int i = 0; i < a.length;i++)

这里的 i < a.length 会被多次访问,应该在循环外部将循环的次数写好

改正后的:

int a[] = new int [10];

int alength = a.length;

for(int i = 0; i < alength;i++)

还可以使用 foreach 的方式进行循环,不过foreach在有些情况下不能很好的适应对应的需求,所以在选循环方式时,注意根据需求进行编写相关循环代码。

2.把返回类型定义为集合接口而不是实现类

3.使用try-with-resource 来自动关闭使用的资源(需要JDK7及以上)

4.对try-catch中,catch块抛出的异常在项目最好是记录到日志中,不要使用e.printStack,直接将信息输出到控制台中。

5.对于一些需要经常改动的,比如IP地址、数据库连接信息等,可能随时需要更换的,将这些信息写入到配置文件中更好

6.确保if/for/while/switch/try语句块不要嵌套三层

这个一般在编写代码时会忘记,不过在自查时应该及时更正

7.去掉技术性代码注释

不应该添加代码注释来使程序膨胀,并降低可读性,不用的代码应该删除掉,如果需要可以从版本控制系统中恢复(这里也涉及到了代码的版本控制及团队协作的问题,后续在相关文章中写下)

8.字符串比较,把常量放在equals的左面

最好把字符串常量放在equals()和equalsIgnoreCase()方法的左面,来对字符串进行比较。这样就防止了空指针异常的产生,因为一个字符串常量不可能被定义为null。 如 if("".equals(param)){}

9.方法复杂度不能超过10

方法复杂度也被称为麦卡布。 它可以用于简单的计算方法内的“for/if/while”等语句的数量. 每当方法的控制流出现分支,圈复杂度就会加1. 每个方法默认有1的圈复杂度,除了存取器方法。 对于下面的关键字或语句,全复杂度都会加一。 If、for、while、case、catch、throw、return(非最后一行时)、&&、||、?。 注意:else\ default\ finally不会增加圈复杂度。 这意味着一个简单的方法出现switch和大块的case分支时,圈复杂度会惊人的高。 使用if体会switch会有相同的圈复杂度,并不会降低。

public void process(Car myCar){ +1 if(myCar.isNotMine()){ +1 return; +1 } car.paint("red"); car.changeWheel(); while(car.hasGazol() && car.getDriver().isNotStressed()){ +2 car.drive(); } return; }

上面这段代码的方法复杂度为5

10.空指针异常

if(!dbCon.isClosed()) dbCon.close(); 这里没有对数据库连接对象 dbCon 进行是否为null判断就进行了关闭的操作,这样会 引起空指针异常 所以一样这样写: if(dbCon != null) if(dbCon.isClosed()) dbCon.close();

11.去掉永远为真/假的条件判断

在写判断时,注意括号中的几个条件是否会导致最终的结果永远为真或为假

12.把变量变成静态变量或者删除

当有多线程或者多个实例的时候,从一个非静态方法更改一个静态变量,很难获得正确的值,并且可能导致错误。

这个规则可能导致:每次一个静态变量从一个非静态方法更改值,这样的问题。

13.检测read了多少字节

错误代码样例 你不能假定read每一次读取数据都能够填满byte数组。相反,你应该检测每次read方法的返回了多少字节的数据。如果不这样做,你可能引入有害的bug。

同样,你不能假定InputStream.skip方法能够跳过指定的字节数,而是应该检测这个方法的返回值。

这个规则将引起一个问题,当InputStream.read方法接受一个数组的返回值时,但是并没有检测这个返回值,并且InputStream.skip方法也没有检测返回值。这个规则同样也适用于nputStream的子类。

解决方法 解决方法 在读取数据前,先判断读取数据的返回值

14.对一个元素没有进行判断

String a = "shihsihishi" if(a.indexOf(",") > 0) 这里a.indexOf(",") > 0 应该写成 a.indexOf(",") >= 0,因为String字符串是从0开始的,不过还是要看具体是使用场景

15.把某一个值实例化或者变成transient

serializable类型的类的属性必须声明为serializable或者transient类型,甚至是这个类没有明确定义为序列化或非序列化。这是因为在加载前,大多数j2ee框架都把对象fulsh到磁盘,一个可序列化的对象没有序列化,非序列化的对象可能导致程序崩溃,并且为攻击者提供了方便。

16.双等号不能用于浮点数比较大小

浮点数的数学运算是不精确的,应为这样的值是存储在二进制文件中。更糟糕的是,浮点类型的数学运算是没有关联的。使用float类型或者double类型进行一系列数学运算,答案会根据运算顺序的不同而不同,因为舍入会发生在每一个操作步骤中。 Even simple floating point assignments are not simple: 即使简单的浮点运算也并不简单。 操作结果将会根据编译器和编译器的配置不同而有所变化。 因此使用==和!=来比较flaot类型和double类型总是会发生错误,并且像其他比较运算符(>,>=,<,<=)也是有问题的,因为他们不能准确计算0和nan类型。 最好的处理方法是避免比较浮点数。当然这是不可能的,你应该考虑用java的 float-handling类型,比如numbers,比如bigdecimal就可以妥善处理浮点数比较。第三个选项看起来不太可行,但是这个结果已经足够接近。比如使用绝对值比较存贮值和期望值之间的误差在允许范围内。注意这并不能覆盖所有的情况(NaN 和 Infinity就不行) 这个规则适用于float类型和double类型的直接或者间接的相等/不相等的比较。

转载于:https://my.oschina.net/weilicheng/blog/706810

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值