代码之家  ›  专栏  ›  技术社区  ›  VonC

API Java 5和更多:我应该返回一个数组还是一个集合?

  •  30
  • VonC  · 技术社区  · 17 年前

    本着 Best Practices: Always return a ____, never a ____ ,我在即将到来的比赛中也面临同样的问题。 migration from JDK1.4.2 to JDK5 and more . (是的,我 知道 , JDK1.4.2 is EOL! ;-)

    对于返回集合的函数(不是简单的 property collections ,我总是更喜欢(在JDK1.4.2中)返回数组而不是通用列表,因为:

    • 它强制返回类型( MyObject[] 而不是对象列表,更多 类型安全 在静态上——就像在“编译”级别中一样)
    • 建议 返回集合的“只读”字符(向集合中添加元素更为复杂,尽管这不如C中的“只读”关键字严格)。这与说它是“不可变”不同,因为数组中的引用仍然可以修改…

    当然,我总是 创造 此返回的数组(我不公开任何“内部”数组)

    现在,在JDK5和更多版本中,我可以使用 List<MyObject> 如果我愿意的话。

    选择返回的好理由是什么 MyObj[] 代替列表或 Collection<MyObject> 当用java5编码时?

    奖金,如果 收藏<myObject> 是否可以:

    • 是否对返回的集合强制使用只读属性?(不) add() remove() 可能的)
    • 对返回的集合强制一个不可变的方面?(即使该集合的引用也无法修改)

    PS: JavaGenericFAQ 不完全有那个。

    4 回复  |  直到 9 年前
        1
  •  37
  •   VonC    17 年前

    将集合(或列表,或根据需要设置)优先于数组。使用泛型可以获得缺少Java 5之前的类型检查。此外,通过只公开接口,您可以稍后自由地更改实现(例如,为LinkedList切换ArrayList)。

    数组和泛型不能很好地混合。所以,如果你想利用仿制药,你应该 通常 避免数组。
    也就是说,你不能一般地创建一个数组。例如,如果t是泛型类型,则“new t[0]”不会编译。您必须执行类似“(t[])new object[0]”的操作,这将生成未选中的强制转换警告。出于同样的原因,不能在没有警告的情况下使用带有varargs的泛型类型。

    使用 Collections.unmodifiableCollection (和类似的方法),您将获得只读约束(使用数组无法实现这一点—您必须返回数组的克隆)。

    不能强制成员不可变,但也不能用数组来实现。

        2
  •  11
  •   mcjabberz    17 年前

    实际上,与集合/列表相比,数组还有一个优势。由于Java通过类型擦除实现泛型的方式,不能有两种方法将集合作为参数,而只有集合的泛型类型不同。

    前任:

    public void doSomething(Collection<String> strs) { ... }
    public void doSomething(Collection<Integer> ints) { ... }
    

    以上两个方法将不会编译,因为javac编译器使用类型擦除,因此无法将类型信息传递给JVM。JVM将只看到两个将集合作为其参数的方法。

    在上述情况下,最好的解决方法是让这些方法以数组作为参数,并在将参数传递给它们时使用集合/列表的toArray()方法。如果您仍然想在上面的方法中使用Copy/List,只需使用java. UTI.SARTRO.ASLISTHER()方法来获取列表。

    前任:

    public void doSomething(String[] strs) {
            List<String> strList = Arrays.asList(strs);
            ...
    }
    
    public void doSomething(Integer[] ints) {
            List<Integer> intList = Arrays.asList(ints);
            ...
    }
    
    public static void main(String[] args) {
            List<String> strs = new ArrayList<String>();
            List<Integer> ints = new ArrayList<Integer>();
            obj.doSomething(strs.toArray());
            obj.doSomething(ints.toArray());
    }
    
        3
  •  4
  •   madlep    17 年前

    在中签出不可修改的*方法 Collections 类以使返回的集合为只读/不可变。这将原始集合包装在一个列表中,该列表阻止访问更改列表本身(尽管元素本身不是不可变的)。

    unmodifiableList 例如。

    对我来说,这取决于如何使用返回的列表。它将传递给哪些其他方法,以及如何使用它?一般来说,我更喜欢泛型集合而不是数组,但会根据具体情况对其进行更改。

    如果您正在做一些关键的事情,阵列的性能可能也会更快。

        4
  •  3
  •   Mark    17 年前

    我的答案被否决了,因为我在课堂上使用代理,而使用代理(代理和反射)是不允许的,因为它会影响一些人的思维性能(许多人甚至不使用反射,但是他们使用Hibernate和Spring,后者使用重新感染、类代理和XML)。

    来自cglib.sourceforge.net项目的增强器,它允许为类创建代理(JDK只支持接口代理)。代理允许您控制对象中的方法,但不能使用反射访问字段。如果你有什么问题,可以问。