美文网首页
《阿里巴巴Java开发手册》阅读手记

《阿里巴巴Java开发手册》阅读手记

作者: VincentPeng | 来源:发表于2019-03-08 08:32 被阅读0次

    一、(四)、7
    【强制】所有的相同类型的包装类对象之间值的比较,全部使用equals方法比较。 说明:对于Integer var = ? 在-128至127范围内的赋值,Integer对象是在
    IntegerCache.cache产生,会复用已有对象,这个区间内的Integer值可以直接使用==进行判断,但是这个区间之外的所有数据,都会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用equals方法进行判断。

    自己测试了一下,确实是这样的,好可怕

        @Test
        public void testInteger() {
            //测试-128 、127
            Integer var1 = -129;
            Integer var2 = -129;
            Integer var3 = -128;
            Integer var4 = -128;
            Integer var5 = 127;
            Integer var6 = 127;
            Integer var7 = 128;
            Integer var8 = 128;
            // 通过以下断言
            assert var1 != var2 : "小于-128,不能使用等等";
            assert var3 == var4 : "等于-128,是不相等的";
            assert var5 == var6 : "等于127,是不相等的";
            assert var7 != var8 : "大于127,是相等的";
            
        }
    

    一、(四)、10
    【强制】序列化类新增属性时,请不要修改serialVersionUID字段,避免反序列失败;如果完全不兼容升级,避免反序列化混乱,那么请修改serialVersionUID值。 说明:注意serialVersionUID不一致会抛出序列化运行时异常。

    • serialVersionUID 用来表明类的不同版本间的兼容性

    • 简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来 的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序 列化,否则就会出现序列化版本不一致的异常。

    • 当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serialVersionUID,类型为long的变 量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的 class才会生成相同的serialVersionUID 。

    • 如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本,未作更改的类,就需要显式地定义一个名为serialVersionUID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。

    • 关于如果使用SOA服务,如果消费者如果和提供者依赖的实体jar包不是一个版本的话,就可能会出现不能反序列化。但是Dubbo默认序列化,使用hession,是直接忽略serialVersionUID的。

    推荐】循环体内,字符串的连接方式,使用StringBuilder的append方法进行扩展。 说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。

    我们来实际看一下

    反编译字节码命令
    javap是 Java class文件分解器,可以反编译,也可以查看java编译器生成的字节码,从而对代码内部的执行逻辑进行分析。

    用法: javap <options> <classes>
    其中, 可能的选项包括:
      -help  --help  -?        输出此用法消息
      -version                 版本信息
      -v  -verbose             输出附加信息
      -l                       输出行号和本地变量表
      -public                  仅显示公共类和成员
      -protected               显示受保护的/公共类和成员
      -package                 显示程序包/受保护的/公共类
                               和成员 (默认)
      -p  -private             显示所有类和成员
      -c                       对代码进行反汇编
      -s                       输出内部类型签名
      -sysinfo                 显示正在处理的类的
                               系统信息 (路径, 大小, 日期, MD5 散列)
      -constants               显示最终常量
      -classpath <path>        指定查找用户类文件的位置
      -cp <path>               指定查找用户类文件的位置
      -bootclasspath <path>    覆盖引导类文件的位置
    
    ##使用javap -c '不带.class后缀的文件名'
    #
      public void testStrppend();
        Code:
           0: ldc           #10                 // String SH
           2: astore_1
           3: iconst_0
           4: istore_2
           5: iload_2
           6: bipush        100
           8: if_icmpge     37
          11: new           #11                 // class java/lang/StringBuilder
          14: dup
          15: invokespecial #12                 // Method java/lang/StringBuilder."<init>":()V
          18: aload_1
          19: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          22: ldc           #14                 // String hello
          24: invokevirtual #13                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
          27: invokevirtual #15                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
          30: astore_1
          31: iinc          2, 1
          34: goto          5
          37: return
    
    把反编译代码翻译一下

    相关文章

      网友评论

          本文标题:《阿里巴巴Java开发手册》阅读手记

          本文链接:https://www.haomeiwen.com/subject/vwrlpqtx.html