2

好吧,我只是想确认一些事情。

我正在为 java 的 Properties 类创建一个包装类,我遇到了一个小问题。

如果我有

public static void set(String key, Object value) { _p.set(key, value.toString()); }

public static void set(String key, SomeClass value) { _p.set(key, value.SomeMethod().toString()); }

Object当其他重载都不够时才调用重载?

4

4 回答 4

4

这是一种非常危险的使用模式,实际上在 Effective Java 中明确建议不要使用。问题是方法签名解析是在编译时静态发生的,因此它不依赖于运行时参数的实际类型,只依赖于它们声明的类型。

于 2012-05-10T11:09:33.047 回答
3

Java 将选择最具体的匹配,在您的情况下,布尔值将使用自动装箱 boolean <-> Boolean 自动转换。如果您使用任何其他类型(如 String),则将使用 Object 变体。

您在Java 语言规范中找到的详细信息 请参阅 8.4.9 重载

添加以回应评论:

您可以使用以下代码轻松测试行为:

class A {
    public void print(Object o) {
        System.out.println("A.print " + o);
    }

    public static void main(String[] args) {
        B b = new B();
        A a = new A();
        b.print("test b");
        a.print("test a");
        ((A) b).print("test a or b");
    }
}

class B extends A {
    public void print(Object o) {
        System.out.println("B.print " + o);
    }
}

印刷:

B.print test b
A.print test a
B.print test a or b

我希望现在更清楚会发生什么。

于 2012-05-10T11:01:33.180 回答
2

这取决于您传递给此方法的引用类型。例如

Objeyt myObject = Boolean.TRUE;
YourClass.set("foo", myObject);

不会调用参数列表中带有布尔值的方法它将选择Object版本。

例如,请参阅java.util.TreeSet(Collection c)jdk 中的构造函数。那里也发生了类似的事情(它检查集合是否实际上是 a SortedSet,但有一个构造函数用于SortedSet)。

尝试

public class A {

    public void method(String str) {
        System.out.println("foo");
    }

    public void method(Object obj) {
        System.out.println("bar");
    }

    public static void main(String[] args) {
        A a = new A();
        Object obj = "A String";
        a.method(obj);
    }

}

这打印bar。奇怪但真实:)

于 2012-05-10T11:12:47.373 回答
1

发布以下示例:

public class Inherit {
  public static void main(String[] args) {
    System.out.println("Hello, Inheritance!");

    Parent parent = new Parent();
    Parent childp = new Child();
    Child childc = new Child();

    System.out.println("===============================");
    parent.print(parent);
    parent.print(childp);
    parent.print(childc);

    System.out.println("===============================");
    childp.print(parent);
    childp.print(childp);
    childp.print(childc);

    System.out.println("===============================");
    childc.print(parent);
    childc.print(childp);
    childc.print(childc);

  }

}

class Parent {
    public void print(Parent x) {
       System.out.println("Parent.print(Parent)");
    }
}

class Child extends Parent {

    public void print(Child x) {
       System.out.println("Child.print(Child)");
    }

    @Override
    public void print(Parent x) {
       System.out.println("Child.print(Parent)");
    }
}

和输出

Hello, Inheritance!
===============================
Parent.print(Parent)
Parent.print(Parent)
Parent.print(Parent)
===============================
Child.print(Parent)
Child.print(Parent)
Child.print(Parent)
===============================
Child.print(Parent)
Child.print(Parent)
Child.print(Child)
于 2017-04-11T00:31:38.967 回答