Java 可以使用instanceof操作符实现两个并行的函数层次结构和这些函数的参数层次结构吗?

Java 可以使用instanceof操作符实现两个并行的函数层次结构和这些函数的参数层次结构吗?,java,instanceof,Java,Instanceof,在以下上下文中使用instanceof运算符是一种不好的做法吗 public interface IWriter { public abstract void write(Dto dto); } public abstract class Dto { private long id; public void setId(long id) {this.id = id;} public long getId() {return id;} } public clas

在以下上下文中使用instanceof运算符是一种不好的做法吗

public interface IWriter {
    public abstract void write(Dto dto);
}

public abstract class Dto {
    private long id;
    public void setId(long id) {this.id = id;}
    public long getId() {return id;}
}

public class DtoA extends Dto {
   ...
}

public class DtoB extends Dto {
   ...
}

public class MyWriterA implements IWriter {
   @Override
   public void writer(Dto dto) {
     if (!(dto instanceof DtoA))
        return;
     ...
   }
}

public class MyWriterB implements IWriter {
   @Override
   public void writer(Dto dto) {
     if (!(dto instanceof DtoB))
        return;
     ...
   }
}
关于这个操作符的使用有很多神话,我并不完全相信 我肯定我所做的不是废话

我有很多不同的编写器实现 我想将其合并到一个接口中。问题不是每个DTO都适用于每个作家。在我的实际代码中,有一个深层的DTO层次结构,它扩展了DtoA和DtoB,并且 DtoA或DtoB的层次结构分支适用于编写器,但仅在少数情况下两者都适用

我应该避免使用抽象类Dto作为抽象
write(Dto Dto)
方法的参数吗

编辑:请阅读已接受答案上的注释。

您看过双重分派或模式吗

基本上,Writer和DTO对象将通过中介调用正确的方法,例如

public void writer(Dto dto) {
   dto.doSomething(writer);
}
调用的
doSomething()
方法取决于
Dto
的类型。您的
Dto
对象将实现
MyWriterA/B
的版本


使用
instanceOf
并不是不可避免的,但通常是一种设计气味,表明某些东西不正确,或者可以做得更好。

有时使用
instanceOf
是不可能的-没有必要感到羞耻

键入IWriter可能会有所帮助:

public interface IWriter<T extends Dto> {
    public abstract void write(T dto);
}
公共接口IWriter{ 公开摘要无效书写(T dto); } 然后

公共类MyWriterA实现IWriter{
@凌驾
公共无效写入程序(DtoA dto){
//不需要instanceof,因为它不能是其他任何东西
...
}
}

也许将这种类型和Brian Agnew的有价值的答案结合起来就可以了。

代码如何调用IWriter?大概你也要确定上面的类型?在这种情况下,你已经知道你需要什么样的作家了。您已经根据类型进行了调度


你的作者并不是真正可以替代的作家,他们只做As等等。在这种情况下,如果你声称他们在继承层次结构中,你不会得到任何东西。

Brian,请详细说明。doSomething()方法的签名是什么?会有writerA版本和writerB版本吗?writer方法是一种writerA方法,假设它是用a B调用的,那么我们称a B的doSomething(writerA)方法?当然不是?好的,这是一个非常有趣的模式。我不确定我是否正确,我认为这会导致与我的代码不同的行为,因为错误类型的对象不会被忽略,它们会被编写。doSomething()方法的具体功能是什么?我有一个IWriter对象(我不知道运行时的确切类型),我从队列中读取DTO(它们的类型也是未知的),但只应写入正确类型的DTO,因此它们实际上处于一个层次结构中…好的,所以你只是把所有的DTO都扔给了一个作家,而他忽略了那些他不理解的。在这种情况下,我认为作者应对他的“规则”负责,因此您的instanceOf实际上很好。Thx现在我了解到这是一种需要使用instanceOf的情况,因为所有其他方法都会导致不同的行为。不幸的是,我对泛型不太了解,但您的方法听起来最有趣。我可以将任何实现Dto的对象传递给MyWriterA#writer(Dto?)吗?或者这会导致编译器错误吗?好的,我检查了它…它会导致编译器错误:)这种处理方法确实很酷,但不适合我的需要,因为它与我的示例代码不同…也许可以发布更多关于如何调用/使用它的上下文(不发布太多代码:))。我们可能会帮你更多。我把标题改得更具描述性。。。如果这没有达到您的目的,请随时再次编辑。
public class MyWriterA implements IWriter<DtoA> {
   @Override
   public void writer(DtoA dto) {
     // No need for instanceof, because it can't be anything else
     ...
   }
}