【问题标题】:How to restrict elements of an ArrayList without using generics如何在不使用泛型的情况下限制 ArrayList 的元素
【发布时间】:2012-06-12 20:00:52
【问题描述】:

假设我有一个Employee 类。如何在不使用泛型的情况下实现仅包含 Employee 元素的 ArrayList?也就是说,没有Arraylist<Employee>,如何限制ArrayList只添加Employee对象?

【问题讨论】:

  • 你为什么不想使用泛型? (只是出于好奇)
  • 可能有时候我们没有java 1.5 .所以在一些旧的应用程序中我们需要限制arraylist,在这种情况下我们需要实现这个逻辑
  • @sartysam:这种想法需要死。 Java 具有出色的向下兼容性。在大多数情况下,使用任何旧 Java 版本编写的应用程序将在最新的 JVM 上运行不变而不会出现任何问题。几乎可以肯定,与使用已过时 10 年的 Java 版本相比,少数不兼容问题更小。

标签: java generics arraylist


【解决方案1】:

扩展ArrayList并自定义add()addAll()方法来检查添加的对象是instanceofEmployee

【讨论】:

    【解决方案2】:

    你可以使用一个包含私有 ArrayList 字段的包装类,比如employeeList,它有一个

    public void add(Employee employee) {
       employeeList.add(employee);
    }
    

    以及允许外部类以受控方式与 ArrayList 交互的任何其他必要方法。

    我发现为此使用组合比继承要好得多。这样,如果您想从 ArrayList 更改为其他内容,例如 LinkedList,甚至是完全不同的内容,您会更轻松。

    【讨论】:

    • +1 对于允许编译时检查的答案,但不幸的是,这意味着它无法使用泛型实现List
    • @Paul:为什么不能使用 List 作为私有变量类型?我不认为这需要泛型。
    • @HovercraftFullOfEels - 可以;我的意思是你的包装类不能实现原始List - 否则add 将采用Object,我们会回到我们开始的地方。
    • @Paul: 但这就是我的意思:employeeList变量的变量类型可以其实是List类型,这个变量引用的对象可以是一个数组列表。 List 使用 Object 作为其 add 方法,这与 ArrayList 没有什么不同,后者只是重写了 List 的方法。这与泛型无关。包装类的公共方法仍然只接受一个 Employee 对象,这就是你可以进行编译时类型检查的地方。
    • @Paul:我明白你现在在说什么了。对不起。我在想私有变量的类型,而你在谈论包装类本身。明白了,是的,你是对的。对不起,我的困惑 - 这是一个漫长的天。
    【解决方案3】:

    您可以使用 Collections.checkedList() - 但您为什么不想使用泛型?

    【讨论】:

    • 在我们安装了 JDK 1.3 的旧应用程序之一中。因此它不支持泛型
    【解决方案4】:

    继承ArrayList 类并将其命名为EmployeeArrayList

    【讨论】:

      【解决方案5】:

      如果您想避免泛型本身,例如为了与非常旧的 Java 版本兼容,那么扩展或包装 ArrayList 将无济于事——您可能想找到或制作另一个具有相同功能的数组实现。

      基本上,ArrayList 只是原始数组的包装器,它在必要时将其数据复制并粘贴到更大的数组中,因此从头开始编写并不是特别困难。

      【讨论】:

      • 没有理由完全重写ArrayList - 最多可以达到与composition approach 相同的效果。
      • 我假设(基于 cmets)作者需要选择使用 Java 版本编译此代码,该版本已过时以至于没有泛型,这(虽然不幸)已经发生给我一次。但是,是的,如果包装或子类化是一个选项,那么其中任何一个都应该是首选。
      【解决方案6】:

      当你“限制”时,你到底想要什么?有两个可能的地方可以设置限制:在编译时或运行时。

      泛型是纯编译时的东西。它可以帮助您编写正确的代码,但您仍然可以绕过它并将错误的类型放入数组中,并且在运行时不会报错。

      另一方面,Collections.checkedList() 之类的东西是运行时限制。当出现错误类型的对象时,它会在运行时引发错误。但如果您没有泛型,它在编译时对您没有帮助。

      所以这两件事是正交的,两者都不是另一个的替代品。你到底想要什么?

      【讨论】:

        猜你喜欢
        • 2010-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-08
        • 1970-01-01
        • 1970-01-01
        • 2021-04-23
        相关资源
        最近更新 更多