Java基础面试:默认值、引用与boolean大小,哪些说法容易背错?
发布时间:2026/10/6 1:54:35 作者:尧图编辑部 阅读量:1,286

原笔记整理了语言特点、面向对象、八种基本类型、命名和 instanceof。大方向可以保留但几个答案把不同层次混在一起字段的默认值套到局部变量、字节码的表示套到内存大小、语言风格套到性能高低。这次按 Java 17 规范核对并用完整程序和编译反例说明。不测对象布局、不跑性能基准也不把一台 JVM 的行为扩大成所有实现的内存承诺。1. 跨平台与面向对象先说明保证范围Java 通常先编译成 class 字节码在兼容的运行环境上执行。但“跨平台”不是没有前提字节码版本、依赖库、JNI、本机文件路径等都可能影响可运行性。面向过程更强调步骤与函数面向对象更强调职责、状态和对象协作两种思想可以在同一程序中共存。封装、继承、多态是工具不自动保证低耦合继承关系设计不当也会增加耦合。原文“面向过程性能高面向对象性能差”不能作为普遍结论。要比较性能先确定实现、算法、数据分布、优化和测试条件。用没有实测的语言标签替代这些条件解释不了一个具体程序为什么慢。2. 八种基本类型值的位宽不等于对象占用类型值或格式的范围字段/数组元素默认值包装类byte8位有符号整数0Byteshort16位有符号整数0Shortint32位有符号整数0Integerlong64位有符号整数0LLongfloatbinary32浮点格式0.0fFloatdoublebinary64浮点格式0.0dDoublechar16位无符号UTF-16代码单元数值为0的字符Characterbooleantrue或falsefalseBoolean这是语言层面的取值与默认值不是对象内存布局表。Integer 还涉及对象或缓存、引用等不能拿 int 的32位直接推出 Integer 对象只占4字节。JLS基本类型。char 默认值不是引用 null二者类型不同。一个 char 也不一定表示一个完整 Unicode 字符某些码点需要两个 UTF-16 代码单元。3. “int默认是0”必须说明它在哪里实例字段、静态字段、数组元素有默认初始化局部变量使用前必须满足明确赋值要求。JLS变量初始化。文件名 DefaultsProbe.javapublic class DefaultsProbe { int count; Integer boxed; boolean enabled; char letter; public static void main(String[] args) { DefaultsProbe p new DefaultsProbe(); System.out.println(p.count); System.out.println(p.boxed null); System.out.println(p.enabled); System.out.println((int) p.letter); int[] numbers new int[2]; System.out.println(numbers[0]); try { int value p.boxed; throw new AssertionError(unboxing unexpectedly succeeded); } catch (NullPointerException expected) { System.out.println(null cannot be unboxed); } } }输出为 0、true、false、0、0、null cannot be unboxed。未初始化的 Integer 字段为 null把它拆箱成 int 才触发这里的异常单纯比较它是否为 null 不会异常。下面则是故意无法编译的局部变量反例不要和上面的程序放在同一个文件里class LocalBeforeInit { void test() { int count; System.out.println(count); } }编译器会报告可能尚未初始化。不存在“局部 int 没赋值运行时就读出0”的语言保证。4. 引用赋值复制的是引用值不是整份对象赋值后a ---- -- 同一个数组 b ---- clone后c ------- 另一个数组容器public class ReferenceProbe { public static void main(String[] args) { int[] a {1, 2}; int[] b a; b[0] 9; System.out.println(a[0]); int[] c a.clone(); c[0] 7; System.out.println(a[0]); System.out.println(c[0]); Object value hello; System.out.println(value instanceof String); System.out.println(value instanceof CharSequence); value null; System.out.println(value instanceof String); String supplementary new String(Character.toChars(0x1F600)); System.out.println(supplementary.length()); System.out.println(supplementary.codePointCount(0, supplementary.length())); } }输出依次为 9、9、7、true、true、false、2、1。这里 int[] 的 clone 复制了基本类型元素若改成对象数组复制数组容器不等于递归复制每个对象。引用也可以指向已经存在的对象不要求每次赋值都用 new。instanceof 测试兼容的运行时类型关系右边也可以是接口null 的结果为 false。编译期不可转换的类型组合可能直接被拒绝不能说任意两个类型都能拿来测试后返回 false。JLS instanceof。5. boolean不要用字节码槽位推算固定内存大小JVM 对许多 boolean 操作使用 int 相关指令boolean 数组有专门的支持JVMS 也描述了 Oracle JVM 数组元素的编码方式。但规范描述抽象机不规定所有 JVM 的具体对象布局。因此不能从这些语句得出“单独 boolean 必定4字节boolean[]元素在所有实现必定1字节”更不能由局部变量槽位推算堆中字段大小。实际占用还受实现、布局和对齐等因素影响。JVMS boolean与抽象机说明。本次没有用内存工具测量更没有把打印 Boolean.SIZE 当办法Boolean 没有数值包装类那样的 SIZE 常量。6. 命名语法规则与风格不是一回事Java 标识符不只支持 ASCII 英文字母还按 Unicode 的标识符规则定义。不能用数字开头不能使用相应关键字在 Java 17单独的下划线也不是合法标识符。美元符号语法上可出现不代表日常名字就应该随意用它。JLS标识符。类名大驼峰、方法变量小驼峰属于约定不是编译器强制所有名字都按该风格。公开顶层类在常规 javac 文件编译中还要注意类名与文件名一致这和“所有类名都是文件名”不同。7. 本次核验了什么本地 JDK 17 编译运行 DefaultsProbe 和 ReferenceProbe核对默认值、null拆箱异常、共享引用、数组复制、instanceof与UTF-16长度局部变量未赋值的反例必须编译失败。另用编译检查验证非法标识符不用“我记得不能这样写”作为唯一依据。基础面试题往往只差一个限定词字段还是局部类型值还是对象占用复制引用还是复制对象把这个限定词补齐答案才能在实际代码里成立。