作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
Java 并发实践的摘录/片段-
@Immutable
class OneValueCache{
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i, BigInteger[] factors) {
this.lastNumber = i;
this.lastFactors = Arrays.copyOf(factors,factors.length); // 1
}
public BigInteger[] getFactors(BigInteger i){
if(lastNumber == null || lastNumber.equals(i))
return null;
else
return Arrays.copyOf(lastFactors,lastFactors.length); // 2
}
}
作者提到
OneValueCache wouldn't be immutable without the copyOf calls in the constructor and getter. Arrays.copyOf was added as a convenience in Java 6; clone would also work.
1) Arrays.copyOf 在使上述类成为 IMMUTABLE 方面扮演什么角色? 如何?
上面的不可变类是这样使用的-
@ThreadSafe
public class VolatileCachedFactorizer implements Servlet{
private volatile OneValueCache cache = new OneValueCache(null, null);
public void service(ServletRequest req, ServletResponse resp){
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
if(factors == null){
factors = factor(i);
cache = new OneValueCache(i, factors); // cache being volatile, hence @ThreadSafe
}
encodeIntoResponse(resp, factors);
}
}
最佳答案
如果您返回 this.lastFactors
而不是返回一个副本,调用者可以这样做(例如)
BigInteger[] lastFactors = cache.getFactors(...);
for (int i = 0; i < lastFactors.length; i++) {
lastFactors[i] = null;
}
从而改变缓存的状态,这应该是不可变的。
构造函数的解释类似。如果构造函数没有复制,调用者可以做
factors = factor(i);
cache = new OneValueCache(i, factors);
for (int i = 0; i < lastFactors.length; i++) {
factors[i] = null;
}
因此再次改变缓存的状态。
经验法则:数组始终是可变的(空数组除外)。因此,如果一个不可变类的状态包含一个数组,那么调用者一定不能拥有对该数组的引用。
关于java - Arrays.copyOf 在使类不可变方面扮演什么角色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38812649/
我有一个构成Mouse角色的Moose类。 package My::Moose::Class; use Moose; has 'mouse_obj' => ( is => 'ro',
我正在玩字符串的位置界面。我知道 How can I slice a string like Python does in Perl 6? ,但我很好奇我是否可以让这件事只为傻笑而工作。 我想出了这个
我是一名优秀的程序员,十分优秀!