我想根据对象的类型执行几个操作,而不使用instanceof.起初我正在考虑基于类型重载方法(如下所示),并认为Java可能会适当地选择方法(基于最具体的对象类).
import java.util.ArrayList;
import java.util.List;
public class TestA {
public static void main(String[] args)
{
List<Object> list = new ArrayList();
list.add(new A());
list.add(new B());
list.add(new C());
list.add(new Object());
TestA tester = new TestA();
for(Object o: list)
{
tester.print(o);
}
}
private void print(A o)
{
System.out.println("A");
}
private void print(B o)
{
System.out.println("B");
}
private void print(C o)
{
System.out.println("C");
}
private void print(Object o)
{
System.out.println("Object");
}
}
class A {
}
class B extends A {
}
class C {
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Object
Object
Object
Object
Run Code Online (Sandbox Code Playgroud)
然而,我所追求的输出是:
A
B
C
Object
Run Code Online (Sandbox Code Playgroud)
instanceofvisitor.accept(this)是class A导致函数visitor.accept(A o)被调用.instanceof因为我读过它是不好的做法; 在这种情况下,它仍然是不好的做法?kka*_*nja 11
我的答案是让A,B和C类实现一个通用接口.
然后他们每个人都可以拥有自己的特定接口.
这样,您可以为所有对象调用相同的方法(从而避免重载方法),并且还可以根据对象的类型(即实例化它的类)确保自定义功能.
这个答案认为修改给定的类及其关系不是一种选择。
有没有办法让Java根据参数对象最具体的类型来选择方法?
Java编译器无法为您转换此行为,因为也许这不是您想要的(在您的情况下,这就是您想要的,但也许其他人不想要这种行为,并且他们不会为他们提供解决方案)。由于您传递的是Object对 的引用print(),编译器将调用print(Object).
如果没有,我可以在不借助instanceof的情况下寻找此类功能的替代方案
您可以将Object其类型包装在包装类中,例如:
public class ObjectWrapper {
private final Object object;
private final int type;
}
Run Code Online (Sandbox Code Playgroud)
这样您就可以安全地转换为 的类型,Object而无需使用instanceof. 虽然这个恕我直言比简单地使用更复杂instanceof,而且实际上它只是创建你自己的instanceof......
老实说,我反对instanceof,因为我读过使用它是不好的做法;在这种情况下,这仍然是不好的做法吗?
在编程中,没有什么总是不好的做法。一切都取决于情况。在这种情况下,我认为您可以使用instanceof并进行不安全的铸造,因为设计需要这样做。不管怎样,如果instanceof语言中存在运算符,那是因为它被使用了。如果这始终instanceof是一种不好的做法,那么它就不会作为语言的一部分而存在。看看这个和这个。
我实际上是在尝试模拟访问者模式,但看起来,访问者模式起作用的原因是双重分派,这使得“接受”的参数在函数调用期间处于正确的类型,特别是访问者.accept(this)在 A 类中会导致调用函数 Visitor.accept(A o) 。
检查我的第二个链接,了解使用访问者模式的缺点。