我有这段代码,
class Test
{
public static void main(String args[])
{
String x = "Hello";
String y = "Bye!";
System.out.printf("This is %s, this is %s", x);
}
}
java编译器编译它,但它显然有错误。我的问题是,为什么编译器没有发现这个错误?如果它甚至无法捕捉到这个小错误,静态打字的好处在哪里?
答案 0 :(得分:7)
printf()
将String和一个vararg对象数组作为参数。您的程序传递符合这些参数类型的参数,因此编译器很高兴。
如果你这样做,编译器会拒绝你的方法调用,例如
Integer a = 23;
System.out.printf(a, x);
因为Integer不是String。
您似乎认为静态类型使运行时错误无法实现。事实并非如此。编译器不知道printf()做什么以及那些%s
在String中的含义。它不知道%s
的数量应该与传递给该方法的参数数量相匹配。即使它确实如此,您也可以将String类型的变量和Object []类型的变量传递给方法,该方法的长度和值仅在运行时已知,而不是在编译时。例如:
String s = readPatternFromUser();
Object o = readFirstArgFromUser();
System.out.print(s, o);
答案 1 :(得分:1)
因为错误是运行时错误,而不是编译时错误。两个%s的字符串替换在运行时发生。编译器不知道你“缺少”y参数。
答案 2 :(得分:0)
传递给printf()方法的(静态)类型是正确的 - 它是一个非法的参数,直到运行时才会被发现。
这与Integer.parseInt("foo")
或传递给方法的正确类型的不合适值的无数其他情况没有什么不同。