传智播客Java基础入门,浅谈JAVA开发规范与开发细节(上

2021/8/6 14:37:09

本文主要是介绍传智播客Java基础入门,浅谈JAVA开发规范与开发细节(上,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

  1. ****

  2. ***/

  3. //通过用户名获取userAccount

  4. userAccount = AccountManager.getUserAccount(userName);

  5. if(userAccount == null){

  6. //为null的操作,抛异常

  7. }

  8. //再去获取名称

  9. groceryStoreName = userAccount.getGroceryStoreName();

  10. if(groceryStoreName == null){

  11. //为null,抛异常

  12. }

  13. //后续一堆业务代码

  14. }

``` 但是我们看下规范后的写法: ```

  1. public void test(String userName){

  2. //中间一堆业务代码和操作

  3. /*****

  4. ****

  5. ***/

  6. //通过用户名获取userAccount

  7. Account userAccount = AccountManager.getUserAccount(userName);

  8. if(userAccount == null){

  9. //为null的操作,抛异常

  10. }

  11. //再去获取名称

  12. String groceryStoreName = userAccount.getGroceryStoreName();

  13. if(groceryStoreName == null){

  14. //为null,抛异常

  15. }

  16. //后续一堆业务代码

  17. }

``` 很明显的可以看出来,代码更清晰明了,也更有逻辑性。另外在申明类属性变量的时候,我们建议将变量申明在一起,分块存放,不建议在类中变量和方法混合在一起使用,例如:

另外在申明类变量的时候,切记不要忘记类变量如果是基础类型,会有默认值,如非必要,在类属性创建中建议使用包装类型,防止因默认值带来的数据不一致等问题,而在方法内创建局部变量的时候,由于基本类型变量没有默认值,需要手动申明值,反而建议使用基本类型,而不是使用包装类,这样同样也可以尽量避免无意的拆箱、装箱行为,在数十万次百万次的情况下,对于程序也会造成一定的影响。

if与大括号

if语句是我们开发中最常见的逻辑分支语句之一,同样的在java中if也会有一些简洁写法,例如逻辑业务仅有一行代码的时候,我们可以省去大括号,直接在if下一行编写业务代码,如下:

1.  `if(flag)`

2.  `count ++;`

3.  `//if以外的逻辑`

4.  `user.setAge(10);`

5.  `......`

</pre>

但是熟悉规范的都知道,无论是阿里规范还是jdk的规范,都不推荐使用简化代码,这是为什么呢?这让我想起了2014年苹果的ios系统爆出来的一个严重安全漏洞(“GoTo Fail 漏洞”),而这个漏洞就和大括号有关系,而对应漏洞的代码大概可以理解为这样:

1.  `if  ((error = doSomething())  !=  0)`

2.  `goto fail;`

3.  `//无论如何都是走到这里,下面再也触发不了了`

4.  `goto fail;`

5.  `if  ((error= doMore())  !=  0)`

6.  `goto fail;`

7.  `fail:`

8.  `return error;`

</pre>

是不是看出来什么了?没错,如果前面的条件生效,就会跳转到fail的操作,返回error,但是如果不满足也会跳转到fail,那么也就是说后续的业务代码无论如何也触发不了了,其实了解这个问题的人其实大概可以猜出来,这里就是多写了一个goto fail;导致编译器认为了别的业务代码,但是假设我们加了大括号,这个问题就会迎刃而解,例如:

1.  `if  ((error = doSomething())  !=  0)`

2.  `{`

3.  `goto fail;`

4.  `//无论如何都是走到这里,下面再也触发不了了`

5.  `goto fail;`

6.  `}`

7.  `if  ((error= doMore())  !=  0)`

8.  `goto fail;`

9.  `fail:`

10.  `return error;`

</pre>

其实这个时候就会发现即使是多写了一行代码,也不会影响整个业务的逻辑,减少了bug产生。看到这里我们似乎明白了,为什么各大规范都建议不省略大括号的写法了。

包装类与基本类型

做Java开发的都知道,Java中默认有八种基本类型,但是同样的也有八种对应的包装类型,很多时候企业开发和使用的时候对于包装类型和基本类型的使用并不规范,往往会导致一部分小的隐患的发生。前面我们有介绍建议在类属性申明的时候使用包装类型,而在方法内建议使用基本类型,这里我们可以再去思考两个开发的时候常用的使用场景:

1.判断两个数值类型的值是否相等

2.创建数值类型

看过阿里手册和JDK规范的应该知道,里面都有一条规范,明确指出基本数值类型的包装类型在比较的时候不允许使用==的方式,而是使用equals,这是为什么呢?我们来看看一个例子:

1.  `Integer a = 100, b = 100, c = 150, d = 150;`

2.  `System.out.println(a == b);//true`

3.  `System.out.println(c == d);//false`

</pre>

可以看到两个Integer类型的变量,值一样的情况下,==比较的结果居然是false?我们通过断点的方式知道 Integer var = ? 形式声明变量,会通过 java.lang.Integer#valueOf(int) 来构造 Inte ger 对象,我们来看看valueOf方法的源码:

1.  `public  static  Integer valueOf(int i)  {`

2.  `if  (i >=  IntegerCache.low && i <=  IntegerCache.high)`

3.  `return  IntegerCache.cache[i +  (-IntegerCache.low)];`

4.  `return  new  Integer(i);`

5.  `}`

</pre>

可以看到,会去判断value的值是否在IntegerCache的范围内,如果在,就会使用IntegerCache中缓存的实例,不存在才会创建新的Integer实例,这个缓存的值,默认是-128到127之间,并且是可以通过配置环境变量的方式动态改变的,这点可以从IntegerCache源码中看到:

1.  `privatestaticclassIntegerCache{`

2.  `staticfinalint low = -128;`

3.  `staticfinalint high;`

4.  `staticfinalInteger cache[];`

5.  `static{`

6.  `// high value may be configured by property`

7.  `int h = 127;`

8.  `String integerCacheHighPropValue =`

9.  `sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");`

10.  `// 省略其它代码`

11.  `}`

12.  `// 省略其它代码`

13.  `}`

</pre>

从这我们也可以看出问题2的答案,为什么很多规范都推荐构建实例的时候是Integer a = 5;的形式,而不是new Integer(5);的原因,可以减少实例的创建,复用缓存对象。接着我们再来看第一个问题,比较和equals比较的区别在哪?我们知道比较的是两个实例对象的内存地址,而equals则是比较的具体的实现,而基本类型的包装类实现实例如果不在缓存范围内,肯定不是同一个对象,逻辑上内存地址肯定是不一样的,所以在超过缓存范围后,比较的结果并不准确,那么我们该如何比较呢?事实上,基本类型的包装类中都有获取具体value的方法,例如Integer中就有intValue的方法,获取具体的值,类型为基本类型,这样我们再去比较就可以了,那么equlas方法为什么可以比较呢?我们就拿Long类型的equals方法的源码来看一下具体实现:

1.  `public  boolean equals(Object obj)  {`

2.  `if  (obj instanceof  Long)  {`

3.  `return value ==  ((Long)obj).longValue();`

4.  `}`

5.  `return  false;`

6.  `}`

</pre>

可以看到这类包装类型的比较其实也就是我们上述说的获取具体value值以后再去==比较的操作。

空指针

空指针基本是每个Java开发人员最恶心的异常也是见过最多的异常之一,可能出现在各种业务代码和场景中,在阿里规范手册中,有很多针对空指针的规范和处理,如下:

【强制】Object 的 equals 方法容易抛空指针异常,应使用常量或确定有值的对象来调用 equals。【推荐】防止 NPE,是程序员的基本修养,注意 NPE 产生的场景:

  1. 返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。反例:public int f () { return Integer 对象}, 如果为 null,自动解箱抛 NPE。

  2. 数据库的查询结果可能为 null。

  3. 集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。

  4. 远程调用返回对象时,一律要求进行空指针判断,防止 NPE。

  5. 对于 Session 中获取的数据,建议进行 NPE 检查,避免空指针。

  6. 级联调用 obj.getA ().getB ().getC (); 一连串调用,易产生 NPE。

可见空指针出现的场景可能会有很多,而在开发中一些必要的检查,减少空指针是每个程序员都应该有的素质,但是有些不规范的操作或者疏忽可能会导致空指针的诞生,例如:

Kafka进阶篇知识点

image

Kafka高级篇知识点

image

44个Kafka知识点(基础+进阶+高级)解析如下

image

开发中一些必要的检查,减少空指针是每个程序员都应该有的素质,但是有些不规范的操作或者疏忽可能会导致空指针的诞生,例如:

Kafka进阶篇知识点

[外链图片转存中…(img-R1OS15es-1628227734833)]

Kafka高级篇知识点

[外链图片转存中…(img-xvvDgZLY-1628227734835)]

44个Kafka知识点(基础+进阶+高级)解析如下

[外链图片转存中…(img-G6ajtECH-1628227734837)]

由于篇幅有限,小编已将上面介绍的**《Kafka源码解析与实战》、Kafka面试专题解析、复习学习必备44个Kafka知识点(基础+进阶+高级)都整理成册,全部都是PDF文档**,有需求的朋友可以戳这里免费下载



这篇关于传智播客Java基础入门,浅谈JAVA开发规范与开发细节(上的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程