【问题标题】:Overloading arguments of inherited types重载继承类型的参数
【发布时间】:2012-05-10 10:56:49
【问题描述】:

好吧,我只是想确认一下。

我正在为 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 重载是否仅在其他重载都不够用时才调用?

【问题讨论】:

  • boolean 不是从Object 派生的,因为它是primitive
  • 我知道原语是什么。可以很容易地成为Boolean
  • 6.5 年后,我上面的评论完全是卑鄙的。对不起。 (:

标签: java inheritance overloading


【解决方案1】:

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

【讨论】:

  • 我想的也差不多。在我问这个问题之前,我已经将其更改为特定类型(没有Object 类型),但问题仍然在我脑海中。
【解决方案2】:

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

您在Java Language Specification 中找到的详细信息 见 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

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

【讨论】:

  • Java 将选择最具体的匹配。
  • @Di-0xide 这不是我说的,也不正确。我说的是对的。参见 JLS。你不会在那里找到像“最新适用的衍生品”这样的华夫饼。
  • 例如,如果有两个类AB,其中B 扩展了A,并且我有一个方法被一个Object 类型的参数重载, AB。当我使用A 类型的对象调用它时,会调用哪个?当我使用B 类型调用时调用哪个?当我使用扩展 A 的类型 C 调用它时调用哪个?
  • @di-0xide 我添加了一个简短的例子。
  • 你的例子不是重载,而是覆盖
【解决方案3】:

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

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

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

参见例如jdk 中java.util.TreeSet(Collection c) 的构造函数。类似的事情也在发生(它检查集合是否实际上是一个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。奇怪但真实:)

【讨论】:

  • 这并不奇怪,但恕我直言,这是完全可以预料的
【解决方案4】:

发布以下示例:

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)

【讨论】:

    猜你喜欢
    • 2014-09-13
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多