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

2023-12-02

随着泛型的引入,我不愿意尽可能地执行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检查的情况下做到这一点。

Thanks


您可以使用双重调用。不承诺这是一个更好的解决方案,但它是一个替代方案。

代码示例

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(...)方法是不内聚的 - 但使用访问者模式中定义的接口可以清除这种气味。

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

在Java中,重写总是在运行时绑定的,但重载稍微复杂一些:动态分派意味着方法的实现将在运行时选择,但方法的签名仍然在编译时确定。 (查看Java 语言规范,第 8.4.9 章欲了解更多信息,还可以查看本书第 137 页的益智游戏“Making a Hash of It”Java 谜题.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

这里的instanceof检查有什么问题吗? 的相关文章

  • Java JFileChooser 与过滤器据称仅显示目录无法仅显示目录

    预先感谢 如果您需要更多信息 请告诉我 示例代码位于底部 我试图解决的问题 我试图通过使用 javax swing filechooser FileFilter 对象来使此 JFileChooser 对象仅显示目录 而不是文件 该对象在ac
  • 如何选择主题与队列

    当我们设计应用程序时如何选择Topic Queue类型实现 我知道 a 如果有多个消费者使用该消息 则使用 Topicb 如果只有一个消费者则使用Queue 请提供更多需要考虑的点 比如并发 消息持久化 负载均衡等等 Thanks Rw 如
  • Spring批处理2.2 JavaConfig

    我正在尝试让 Spring Batch 2 2 与 JavaConfig 一起使用 如今他们有一个 EnableBatchProcessing设置很多东西的注释 默认情况下 该注释使用数据源作为其作业数据 但我们不想保存此数据 也不想为其创
  • HQL - 分页的行标识符

    有谁知道HQL是否有一个关键字来标识行 例如ROWID或ROWNUM 我想使用 HQL 实现分页 但我无法使用 setMaxResult 或 setFirstResult 因为我不直接使用会话对象 因此不使用 Query 对象 而只是将查询
  • 单击按钮时更改照片

    import javax swing Icon import javax swing ImageIcon public class Stage1 extends javax swing JFrame int score 0 int iter
  • 在java中将HTML转换为RTF?

    我需要将 HTML 转换为 RTF 我正在使用以下代码 private static String convertToRTF String htmlStr OutputStream os new ByteArrayOutputStream
  • 问题:将大数据传递给第二个 Activity

    我有一个奇怪的问题 我在网上浏览但没有找到答案 我仍然是android编程的初学者 那么让我们开始吧 我想做的就是用一些数据调用第二个活动 它适用于小数据 但如果数据变大 第二个 Activity 将不会显示 第一个 Activity 将完
  • java中简单程序中的“未为类型定义方法”错误

    所以我只是想学习 Java 在观看了一些教程并阅读了一些基本内容之后 我对为什么它无法运行感到困惑 package Test public class TestProg public static void main String args
  • Apache HttpClient 4.x 在上传较大文件时表现奇怪?

    我正在使用 java 和 scala 开发和测试一个简单的客户端 服务器应用程序 The server是基于com sun net httpserver HttpServer并允许使用 POST 和 PUT 操作通过基本的 RESTful
  • Spring Data JPA 规范继承

    我有三个实体 如下所示 Entity Inheritance strategy InheritanceType JOINED DiscriminatorColumn name type public abstract class Emplo
  • Java写入ByteArrayOutputStream内存泄漏

    我正在将图像字节写入ByteArrayOutputStream然后通过套接字发送它 问题是 当我这样做时 ImageIO write image gif byteArray 内存增加很多 有点内存泄漏 我用这个发送 ImageIO writ
  • 无法在 PHP 中接收 JSON POST 请求

    我正在将 JSON 对象从 Java 传递到 PHP 我正在使用 jdk 1 8 和 WAMPserver 下面是Java代码 import java io IOException import org apache http client
  • java应用程序,线程在终止MySQL连接后挂起

    我有一些工作线程正在运行 其中包括 MySQL 和 mysql connector java 5 1 20 当我杀死一些 SQL 语句 使用 mysql 客户端的kill 连接id 时 java线程挂起 这应该抛出一些异常 jstack 打
  • Python父类访问子私有变量

    以下代码会生成错误 class A object def say something self print self foo print self bar class B A def init self self foo hello sel
  • 为什么 (Oracle) JVM 对内存使用有固定上限 (-Xmx)?

    本着提问的精神Java 为什么存在 MaxPermSize https stackoverflow com questions 3356005 java why does maxpermsize exist 我想问一下为什么Oracle J
  • 在同步子句中抛出异常的副作用?

    从同步子句中抛出异常是否有任何不清楚的副作用 锁会发生什么情况 private void doSomething throws Exception synchronized lock doSomething 我没有看到任何副作用 The 锁
  • 方法中缺少 return 语句错误

    我正在尝试编写一个返回计算机 MAC 地址字符串的静态方法 该函数本身可以在此处找到 http www mkyong com java how to get mac address in java http www mkyong com j
  • SwingWorker 和 Executor 的区别

    我正在使用 SwingWorker 在我正在制作的应用程序上执行一些重负载任务 虽然今天我遇到了 Executor 类和这个例子 Executors newCachedThreadPool execute new Runnable publ
  • Java中有没有办法随机获取HashMap的值?

    Java中有没有办法随机获取HashMap的值 这有效 Random generator new Random Object values myHashMap values toArray Object randomValue values
  • allure2 侦听器在控制台中输出步骤

    我正在使用 Allure2 和 TestNG 我想编写自己的侦听器 在控制台输出中打印 Steps 我在 allure 中看到了 StepLifecycleListener 接口 但我无法在 TestNg 中实现此侦听器 有什么指点吗 Ov

随机推荐