gpt4 book ai didi

java - HashSet 在构造函数中调用可覆盖的方法

转载 作者:行者123 更新时间:2023-11-30 07:01:13 24 4
gpt4 key购买 nike

在构造函数中调用可重写的方法是不好的做法(参见 this link )。这将始终调用类中定义的方法而不是派生类的方法。在 Java 中 HashSet有一个接受 Collection 的构造函数。此方法委托(delegate)给 addAll 方法。我的问题是为什么这不会破坏 HashSet 的任何派生类。

Constructs a new set containing the elements in the specified collection. The HashMap is created with default load factor (0.75) and an initial capacity sufficient to contain the elements in the specified collection. Parameters: c the collection whose elements are to be placed into this set Throws: java.lang.NullPointerException if the specified collection is null

public HashSet(Collection<? extends E> c) {
map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}

最佳答案

答案是它确实潜在地破坏了子类。很容易证明:

BrokenSet.java:

import java.util.*;

public class BrokenSet<E> extends HashSet<E> {
private final List<E> list = new ArrayList<E>();

public BrokenSet(Collection<? extends E> c) {
super(c);
}

@Override public boolean add(E item) {
if (super.add(item)) {
list.add(item);
return true;
}
return false;
}
}

主要.java:

import java.util.*;

public class Main{

public static void main(String[] args) {
Collection<String> strings = Arrays.asList("x", "y");
Set<String> set = new BrokenSet<>(strings);
}

}

运行Main,你会得到:

Exception in thread "main" java.lang.NullPointerException
at BrokenSet.add(BrokenSet.java:12)
at java.util.AbstractCollection.addAll(Unknown Source)
at java.util.HashSet.<init>(Unknown Source)
at BrokenSet.<init>(BrokenSet.java:7)
at Main.main(Main.java:7)

...因为当 super 构造函数运行时,它调用 BrokenSet.add 期望 list 为非空。

需要仔细编写子类以避免这成为一个问题。 (例如,您可能想看看 LinkedHashSet 做了什么。)

关于java - HashSet 在构造函数中调用可覆盖的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30006279/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com