好吧,我只是想确认一些事情。
我正在为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
重载吗?
这是一种非常危险的模式,实际上在《Effective Java》中明确建议不要使用这种模式。问题是方法签名解析在编译时静态发生,因此它不依赖于运行时参数的实际类型,只依赖于它们声明的类型。
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
我希望现在更清楚发生了什么。
这取决于您传递给此方法的引用类型。例如
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。奇怪但真实:)
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)