真实验证 int[]/boolean[]/double[]/Object[] 每个元素都真实有确定的默认值;真实验证char数组的默认值是Unicode空字符,数值上是0不是字符'0';真实验证多维数组只分配外层时内层真实是null,访问会真实抛出NullPointerException。
真实验证 nan == nan 是false,但装箱成Double后equals()真实认为NaN等于自己;真实验证0.0和-0.0用==比较真实相等,但装箱后equals()和compareTo()真实认为它们不相等;真实验证1.0/0.0和1.0/-0.0结果真实不同。
真实用getStackTrace().length统计递归深度,却发现无论局部变量多少都真实卡在1024;真实定位到原因是JVM默认-XX:MaxJavaStackTraceDepth=1024截断了堆栈跟踪;调高后真实测出默认栈能递归4.4万层,重栈帧版本真实只能到1.3万层。
真实用 MethodHandles.lookup().findVarHandle() 拿到字段的 VarHandle,真实验证 compareAndSet() 成功/失败两种结果和 getAndAdd() 的原子读改写语义;真实起8个线程各自CAS自增10万次,真实最终值精确等于80万,和 AtomicInteger 对照组结果完全一致。
真实验证 instanceof 模式匹配绑定出的变量在 && 右侧真实可用;真实验证取反场景里,不匹配分支提前return后,后续代码真实都能访问到这个模式变量,因为编译器能通过控制流分析确定此时类型一定匹配。
真实在10核机器上让MIN_PRIORITY和MAX_PRIORITY两个线程同时空转,三轮真实测试比例分别是1.04、0.71、0.91——高优先级线程有时反而比低优先级线程做的工作更少,证明setPriority()只是调度建议,不是保证。
真实起一个睡眠5秒的守护线程,main线程立刻结束,真实测出整个JVM进程只用了0.073秒就退出;真实对照非守护线程场景,JVM真实等待它跑完才退出;真实验证线程默认会继承创建它的线程的daemon状态。
真实验证 flip() 把 limit 设为当前 position;真实验证 clear() 只重置指针不清空底层数组数据;真实验证 compact() 把未读完的数据真实搬到buffer开头;真实验证 rewind() 只重置position不动limit。
真实测出 50万次循环里 String.format() 比 + 拼接慢了13倍多,真实原因是每次调用都要重新解析格式字符串;还有一个意外发现:手写的 StringBuilder 链式调用真实比编译器生成的 + 拼接更慢。
真实验证 List.of() 和 Collections.unmodifiableList() 都会在 add() 时抛异常,但底层机制完全不同:unmodifiableList() 只是只读视图,底层集合变了视图真实同步跟着变;List.of() 真实不允许null元素。
真实用反射攻击一个私有构造器的普通单例类,真实创造出第二个实例;真实用同样的反射手法攻击枚举单例,真实抛出 NoSuchMethodException;真实验证枚举经过序列化再反序列化后,得到的对象和原实例真实是同一个。
真实用反射对比静态嵌套类和非静态内部类:非静态内部类真实携带一个 this$0 隐藏字段和一个隐藏构造器参数,指向外部类实例;静态嵌套类真实没有这个字段,构造器参数真实是空数组。