【问题标题】:Why isn't Random class static?为什么 Random 类不是静态的?
【发布时间】:2013-01-20 12:38:28
【问题描述】:

在 Java 中,我们有静态类 Math。您不需要创建它的对象,所以它是静态的。另一个是随机类。我们不需要创建它的实例,那为什么它也不是静态的呢?我的课程我经常使用随机数,当必须在每个课程中创​​建字段 rand 以生成随机数时,我会很生气。那么为什么它不是静态的呢?

【问题讨论】:

  • 嗯,Java 中的顶级类不能声明为静态,您确实需要创建Random 的实例。基本上,您问题的两个前提都不正确。
  • 数学中有一个静态的 random()。
  • 一个更好的问题应该是:“为什么Random 类不是final?”

标签: java random


【解决方案1】:

Random 类具有状态,包括它在其序列中的位置,因为产生的值并不是真正随机的,只是一个伪随机序列。

这可以通过用相同的种子初始化两个实例来证明。

Random a = new Random(123);
Random b = new Random(123);
for (int i = 0; i < 5; i++) {
    System.out.println(a.nextInt() + "," + b.nextInt());
}

输出

-1188957731,-1188957731
1018954901,1018954901
-39088943,-39088943
1295249578,1295249578
1087885590,1087885590

如果使用默认构造函数 Random() 创建,则种子会根据当前时间(以纳秒为单位)+ 静态计数器进行初始化,这意味着不同的实例很可能有不同的序列。

【讨论】:

  • 如果使用默认构造函数 Random() 创建,则种子会使用当前时间(以毫秒为单位)进行初始化 -- 这是不正确的,即使默认 @ 987654323@ 比 System.currentTimeMillis() 更复杂
  • @bestsss 抱歉,您是对的。我正在查看 java.util.Random 的一些非常古老的来源(令人讨厌的是谷歌上的第一个匹配项之一)。使用 System.currentTimeMillis() 曾经是 1.5 之前的行为,但现在正如您所说,更加复杂。
  • 是的,它在 1.5 中改变了,它确实只有毫秒(很蹩脚)
【解决方案2】:

确实需要创建实例,因为随机数生成器具有状态。具体来说,就是控制伪随机序列中当前位置的状态。

如果您想要多个独立的生成器(不共享状态),那么您需要单独的实例。

【讨论】:

    【解决方案3】:

    一切都与种子有关。如您所知,我们谈论的不是真正的随机数,而是伪随机数。当您知道第一个数字时,您可以计算其他数字。这就是为什么我们使用所谓的“种子”的原因。 Random 的每个对象都有不同的种子。如果Random 是静态的,你就不可能有两个不同的种子。请注意,setSeed() 方法会影响所有随机数生成器(我们通常只想更改一个)。

    【讨论】:

      【解决方案4】:

      原因是您可能需要多个独立的随机数生成器。这是通过拥有多个Random 实例来实现的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-16
        • 2010-10-25
        • 2014-12-27
        • 1970-01-01
        • 2012-12-04
        • 2014-09-27
        • 1970-01-01
        相关资源
        最近更新 更多