-3

我有这样的代码:

String stringRef = new String("Java");                    // (1)

System.out.println("(2): " + stringRef.getClass());       // (2)
System.out.println("(3): " + stringRef.length());         // (3)

Object objRef = stringRef;                                // (4)

// System.out.println("(5): " + objRef.length());            // (5) Not OK.
System.out.println("(6): " + objRef.equals("Java")); 

为什么我不能length()在第 (5) 行调用;equals()第 (6) 行将调用哪个类?

4

6 回答 6

1

equals已声明,Object因此您可以调用它;length不是。编译器不会尝试确定究竟引用了什么对象类型objRef;它只有在知道它是一个对象的情况下才能工作。

Java 编译器根据点运算符左侧的表达式的静态类型静态解析要调用的方法的签名。多态性和动态分派的概念仅适用于决定调用哪个覆盖方法。

于 2013-01-17T09:49:15.227 回答
0

你不能这样做,因为子类的方法不在你的超类中。在这种情况下,尽管 String 是 Object 的子类,因为 length() 没有在 java.lang.Object 类中声明,但它不可能在其实例上调用 length。

然而,equals() 方法在字符串类中被覆盖,因此将调用字符串的 equals()

于 2013-01-17T09:48:56.150 回答
0

对于编译器,objRef是 的一个实例Object,它没有任何名为 的方法length()。另一方面,equals()是一个来自Object并继承于的方法String,这就是程序运行正确的原因。

于 2013-01-17T09:49:29.160 回答
0

length() 方法是字符串独有的。通过将其分配给一个对象,Java 不再知道它是一个字符串。

陈词滥调:所有的圆都是形状,不是所有的形状都是圆。

如果您执行以下操作,它将起作用:

System.out.println("(5): " + ((String)objRef).length());

在这里,您首先将类型转换为字符串,然后调用 length()。

于 2013-01-17T09:49:58.047 回答
0

当您有Type引用时,您只能调用对 公开且可见的方法或访问字段Type,即Type自己的方法或Types 超类的公开方法。

在这种情况下,Object 定义了方法equals和许多其他方法,因此您可以使用它们。

于 2013-01-17T09:50:08.187 回答
0

它是引用类型而不是实际对象,它定义了可以访问的所有方法。因此,即使您的超类引用包含子类对象,您也不能使用超类引用访问子类方法。

于 2013-01-17T09:50:24.090 回答