Java中switch case返回不同类型值给var变量,其数据类型是否由运行时返回值决定?
不是的,Java作为静态类型语言,变量output的数据类型在编译阶段就已经确定了,和运行时的输入完全无关。你之所以会有这个疑问,可能是因为看到不同输入输出了不同类型的结果,但这只是多态的表现,并不代表变量类型是运行时动态决定的。
下面具体拆解原因:
var的本质是编译时类型推断
var关键字只是让编译器帮你自动推导变量的类型,而不是让变量变成动态类型。编译器会根据变量的初始化表达式(也就是你的switch表达式)来确定output的固定类型,这个过程在代码编译完成后就彻底结束了,运行时不会再改变变量的类型。switch表达式的类型推导规则
对于switch表达式,编译器会找出所有case分支返回值的最具体的共同超类型——也就是所有分支的返回值都能向上转型到的最接近的类型。看你的代码片段:var output = switch (input){ case 1 -> "one"; // String类型 case 2 -> '2'; // char自动装箱为Character case 3 -> 3.14; // double自动装箱为Double default -> 10; // int自动装箱为Integer };这些分支的返回类型(String、Character、Double、Integer)的共同最具体超类型是
Object & Serializable & Comparable<?>,日常开发中咱们可以简单理解为Object(所有Java类的根父类)。运行时的表现只是多态的体现
你看到不同输入输出不同结果,是因为这些值都被向上转型为output的编译时类型(Object),而System.out.println会自动调用对象的toString()方法,不同类型的对象toString()实现不同,所以展示了不同的输出。但output变量本身的类型从编译完成后就固定了,不会随输入变化。
可以做个简单验证:如果在代码后面加一行output = new ArrayList<>();,编译器会直接报错,因为ArrayList并不符合output的编译时类型约束——这就直接证明了变量类型是编译时确定的,和运行时输入无关。
内容的提问来源于stack exchange,提问作者mps88

