为什么他们甚至在被要求之前就举行了这么多实例(33)?他们从哪里获得16号?

Har*_*nam 3 java biginteger bigint

当我研究静态块时,我想在java源代码中看到它的用法.所以我提到了java.math.BigInteger.java.那里的静态块是这样的

/**
 * Initialize static constant array when class is loaded.
 */
private final static int MAX_CONSTANT = 16;
private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];
private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];
static {
    for (int i = 1; i <= MAX_CONSTANT; i++) {
        int[] magnitude = new int[1];
        magnitude[0] = i;
        posConst[i] = new BigInteger(magnitude,  1);
        negConst[i] = new BigInteger(magnitude, -1);
    }
}
Run Code Online (Sandbox Code Playgroud)

代码浏览器中的静态块代码

从这一点来看,我感觉他们正在创建33个BigInteger实例并将其保存在posConst和negConst中.然后当人们在BigInteger.java:valueOf中调用valueOf时

如果值介于-16到16之间,则取自posConst和negConst并给出.如果超出此范围,则会创建新实例.

我可以理解,如果用户询问该列表中的一个,他们正在持有实例以便随时提供.他们持有33个实例的基础或概率.这不是浪费记忆.为什么不在用户询问时创建,只创建该特定实例.

我无法理解在这种逻辑中获得的权衡.请帮忙 .我在理解这段代码时出错了.如果是这样请帮助.

Mik*_*Hay 5

这实际上是为了节省内存(以及创建对象所花费的时间).使用BigIntegers的程序可能有许多相同数字的副本,通过只存储BigInteger(1)的一个实例,您可以拥有数十万个对该数字的引用,但只需要创建一个对象.

值得注意的是,引用类时会发生静态初始化,因此不使用BigInteger的程序将不会存储此数组.在使用BigInteger的程序中,最糟糕的情况是你要存储33个你不需要的对象,但在最好的情况下,你只需要参考这些常量就可以节省数千个对象的创建和存储.

这被称为Flyweight模式.

现在,为什么要存储这些特定的常量,而不是程序中使用的确切对象?后者需要将程序中使用的每个BigInteger存储在一个哈希表中,并在每次创建一个新的BigInteger时检查该表,这比现有的解决方案在内存和计算时间上要贵得多.您还必须担心表的并发修改,因此也会涉及锁定.简而言之,默认情况下,记住程序中使用的确切对象太昂贵了.一些在-16到16范围之外重复使用大量BigIntegers的程序将自己实现.

小数字通常在程序中更常出现,这就是选择这些特定值进行记忆的原因.