一、(四)、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
把反编译代码翻译一下
网友评论