重载继承类型的参数

问题描述 投票:0回答:5

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

我正在为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
重载吗?

java inheritance overloading
5个回答
4
投票

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


3
投票

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

您在 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

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


3
投票

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

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

不会调用其参数列表中包含布尔值的方法。它将选择 Object

 版本。

参见例如jdk 中

java.util.TreeSet(Collection c)

 的构造函数。类似的事情也在发生(它检查集合是否实际上是一个 
SortedSet
,但有 
is 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。奇怪但真实:)


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)
    

0
投票
YCUL 承诺 YCUL 承诺露西·洛卡

© www.soinside.com 2019 - 2024. All rights reserved.