当前位置: 首页 > 面试题库 >

这里的instanceof检查有什么问题吗?

公风史
2023-03-14
问题内容

随着泛型的引入,我不愿意执行instanceof或强制转换。但是在这种情况下,我看不到解决方法:

for (CacheableObject<ICacheable> cacheableObject : cacheableObjects) {
    ICacheable iCacheable = cacheableObject.getObject();
    if (iCacheable instanceof MyObject) {
        MyObject myObject = (MyObject) iCacheable;
        myObjects.put(myObject.getKey(), myObject);
    } else if (iCacheable instanceof OtherObject) {
        OtherObject otherObject = (OtherObject) iCacheable;
        otherObjects.put(otherObject.getKey(), otherObject);
    }
}

在上面的代码中,我知道ICacheables只能是MyObject或OtherObject的实例,根据此,我想将它们放入2个单独的映射中,然后进行进一步处理。

如果没有我的instanceof check,还有其他方法可以做到这一点,我很感兴趣。

谢谢


问题答案:

您可以使用双重调用。无可否认,这是一个更好的解决方案,但这是另一种选择。

import java.util.HashMap;

public class Example {

    public static void main(String[] argv) {
        Example ex = new Example();
        ICacheable[] cacheableObjects = new ICacheable[]{new MyObject(), new OtherObject()};

        for (ICacheable iCacheable : cacheableObjects) {
            // depending on whether the object is a MyObject or an OtherObject,
            // the .put(Example) method will double dispatch to either
            // the put(MyObject) or  put(OtherObject) method, below
            iCacheable.put(ex);
        }

        System.out.println("myObjects: "+ex.myObjects.size());
        System.out.println("otherObjects: "+ex.otherObjects.size());
    }

    private HashMap<String, MyObject> myObjects = new HashMap<String, MyObject>();
    private HashMap<String, OtherObject> otherObjects = new HashMap<String, OtherObject>();

    public Example() {

    }

    public void put(MyObject myObject) {
        myObjects.put(myObject.getKey(), myObject);
    }

    public void put(OtherObject otherObject) {
        otherObjects.put(otherObject.getKey(), otherObject);
    }

}

interface ICacheable {
    public String getKey();
    public void put(Example ex);
}

class MyObject implements ICacheable {

    public String getKey() {
        return "MyObject"+this.hashCode();
    }

    public void put(Example ex) {
        ex.put(this);
    }
}

class OtherObject implements ICacheable {

    public String getKey() {
       return "OtherObject"+this.hashCode();
    }

    public void put(Example ex) {
        ex.put(this);
    }

}

这里的想法是-
而不是强制转换或使用instanceof-而是调用iCacheable对象的.put(...)方法,该方法将自身传递回Example对象的重载方法。调用哪种方法取决于该对象的类型。

另请参阅“
访客”模式。我的代码示例ICacheable.put(...)发出了臭味,因为该方法具有内聚力-
但使用Visitor模式中定义的接口可以清除该异味。

为什么我不能直接this.put(iCacheable)Example班级打来电话?

在Java中,重载总是在运行时绑定的,但是重载则稍微复杂一些:动态调度意味着将在运行时选择方法的实现,但是方法的签名仍然是在编译时确定的。(有关更多信息,请查看Java语言规范的第8.4.9章,还请参阅Java
Puzzlers一书的第137页的益智游戏“为其制作哈希” 。)



 类似资料:
  • 奇怪的事情正在发生......我真的不明白为什么......这篇文章只有在将id参数类型从int更改为object时才有效。 我知道最好的方法是在url中设置值。。。然而我试图避免这件事。。。我的首选是将值作为json发布 public IHttpActionResult Gettest(int id)=不工作! {“Message”:“未找到与请求URI匹配的HTTP资源”http://loca

  • 我是GraphQL的新手,我正试图做一个突变来从我的数据库中删除一篇文章,但我不知道如何删除。我使用Node.js,猫鼬和GraphQL。 这是我的模式的变异。 这是我在调用API删除文章时使用的查询。 我做错了什么? 我收到一个错误的400请求。消息:“无法查询类型为“变异”的字段“删除”

  • 提示:Extra content at the end of the document这样的错误

  • 问题内容: 我已经为Employee类的父类是抽象的并且父类中的clone()方法是抽象的编写了此克隆方法。我想用此代码复制Employee对象的原始数据类型,而不是复制每个原始数据单独键入,但是此代码在我调用clone()方法的行中有问题。(此代码在Employee类中) 错误是:来自对象类型的方法clone()不可见。 但是我的Employee类在类层次结构中,可以访问Object类中受保护的

  • 我有一个关于书库的问题...我想写一个有3个堆栈的程序,我想在每个堆栈上添加这些操作(我应该使用数组): 1.创建堆栈2。按3号。流行音乐4号。显示每个堆栈的顶部 我写的程序,但我遇到了这些错误: 错误4错误LNK2019:未解析的外部符号“public:int\u thiscall stack::IsFull2(void)”(?IsFull2@stack@@QAEHXZ)在函数“public:v

  • instanceof 操作符用于检查一个对象是否属于某个特定的 class。同时,它还考虑了继承。 在许多情况下,可能都需要进行此类检查。例如,它可以被用来构建一个 多态性(polymorphic) 的函数,该函数根据参数的类型对参数进行不同的处理。 instanceof 操作符 语法: obj instanceof Class 如果 obj 隶属于 Class 类(或 Class 类的衍生类),