在Object o =“”的帮助下创建的对象类型;

时间:2012-03-24 19:37:22

标签: java

说,有以下示例:

class Super {
    public int i = 3;
    public void m(Object o) {
        System.out.println("Object  " + i);
    }
    public void m(String o) {
        System.out.println("String  " + i);
    }
}

public class Sub extends Super {
    public Sub() {
        i = 5;
    }
    public static void main(String[] args) {
        Super s = new Sub();
        Object o = "";
        s.m(o);
        s.m("");
    }
}

此代码的结果是:

Object 5
String 5

但我认为会是:

String 5
String 5

不要引用set String作为此对象的类型?肯定有一些在引用的帮助下转换为String的情况,所以我对这个基本的例子有点困惑。提前谢谢。

4 个答案:

答案 0 :(得分:3)

方法的类型在编译时确定,而不是在运行时确定。 dynamic dispatch仅存在于“参数”this中 - 对static typing种语言(如java)中的参数没有动态调度。

编译器“选择”应该调用哪个方法,并且由于o的类型为Object - 它选择m(Object) - 它无法知道动态类型{ {1}}实际上是o

如果您有兴趣 - 在某些情况下克服此问题的常用方法是使用visitor design pattern

在您的具体情况下,为了“强制”激活String,您应该使用m(String)

答案 1 :(得分:2)

sb.m(o)中,您使用Object引用调用m(),因此Java会选择该重载。 Java不会选择比传递它的引用类型更具体的重载。它会继续上传继承链。假设你没有m(String o),调用sb.m("Hello")仍然是合法的,但它会调用对象版本。

如果你要做sb.m((String) o),你会得到预期的行为。

答案 2 :(得分:1)

您将对象声明为Object,因此其类型为Object。 Java中的类型是强大且静态的,因此当您将对象声明为类型Type时,它的类型将是终身类型。

如果您希望它是一个字符串,则必须使用toString方法或强制转换(String)o

答案 3 :(得分:0)

您正在将字符串向下转换为对象。你在做什么与此类似。

public class Sub extends Super {
    public Sub() {
        i = 5;
    }
    public static void main(String[] args) {
        Super s = new Sub();
        Object o = "";
        System.out.println("Object Type = " + o.getClass().getName());
        s.m(o);
        s.m((Object)"");
    }
}