我有以下设置:
public class SomeUtil {
public static void doSmth(boolean b) {
System.out.println("boolean");
}
public static void doSmth(String b) {
System.out.println("string");
}
public static void doSmth(Object b) {
System.out.println("object");
}
}
public interface SomeCl {
<T> T getAttribute(Object var1);
}
public class SomeClImpl implements SomeCl {
@Override
public <T> T getAttribute(Object var1) {
Boolean o = Boolean.TRUE;
return (T)o;
}
}
public class Demo {
public static void main(String[] args) {
SomeCl someCl = new SomeClImpl();
SomeUtil.doSmth(someCl.getAttribute(Boolean.TRUE));
}
}
当我运行 main 方法时,执行失败并出现 ClassCastException:
线程“main”中的异常java.lang.ClassCastException:类java.lang.Boolean无法转换为类java.lang.String(java.lang.Boolean和java.lang.String位于加载器'的模块java.base中bootstrap') 在 Demo2.main(Demo2.java:4)
所以问题是:为什么 JVM 试图将 Boolean 转换为 String?为什么不反对?
附注请不要建议我在 someCl.getAttribute(arg) 方法调用之前手动转换它或像 someCl./>getAttribute(arg)
那样调用它Java 编译器选择调用
doSmth(String b)
而不是 doSmth(Object b)
,因为语言规则要求选择最具体的方法。
编译器不知道您传递给
doSmth
的参数类型,该参数具有通用返回类型,因此它会选择最具体的方法。
为什么 JVM 试图将 Boolean 转换为 String?为什么不反对?
嗯,出现这种情况是因为 原始类型是任何不从 java.lang.Object 继承的类型!
这与你不能这样做的原因是一样的:
public class SomeUtil {
// Boolean instead of boolean
public static void doSmth(Boolean b) {
System.out.println("boolean");
}
public static void doSmth(String b) {
System.out.println("string");
}
public static void doSmth(Object b) {
System.out.println("object");
}
}
Java 将
Boolean
理解为 Object
,因此您将收到:
java.lang.Error: Unresolved compilation problem:
The method doSmth(Boolean) is ambiguous for the type SomeUtil
因为Java不知道你要调用
doSmth(Boolean b)
还是doSmth(Object b)
,两者都是Objects
。
但是如果你像这样改变 main 方法:
public class Demo {
public static void main(String[] args) {
SomeCl someCl = new SomeClImpl();
SomeUtil.doSmth((boolean) someCl.getAttribute(Boolean.TRUE));
}
}
Java 会理解它是一个
Boolean
。