上一篇文章,我们介绍了几种随机数的生成策略。
那么接下来,我们来分析一下JVMRandom存在的问题。
当我们如下正常构建一个随机数的时候,是没有任何问题的。
JVMRandom jvmRandom = new JVMRandom();
int i = jvmRandom.nextInt(10);
System.out.println(i);
既然JVMRandom底层调用的是Random的构造函数,那么是否也是可以设置seed值呢?
我们来验证一下
JVMRandom jvmRandom = new JVMRandom();
jvmRandom.setSeed(2);
int i = jvmRandom.nextInt(10);
System.out.println(i);
唰~报错了
Exception in thread "main" java.lang.UnsupportedOperationException
at org.apache.commons.lang.math.JVMRandom.setSeed(JVMRandom.java:71)
at com.ossa.producer.controller.ProducerController.main(ProducerController.java:61)
让我们看一看源码,一探究竟。

JVMRandom继承了Random,并重写了setSeed方法。
并且已经不支持设置种子值。
源码如下,当constructed值为false时,就会抛出异常。
/**
* Unsupported in 2.0.
*
* @param seed ignored
* @throws UnsupportedOperationException
*/
public synchronized void setSeed(long seed) {
if (this.constructed) {
throw new UnsupportedOperationException();
}
}
追溯一下constructed值,默认是false
/**
* Ensures that only the parent constructor can call reseed.
*/
private boolean constructed = false;
但是,我们观察其结构可以发现,它只有一个无参构造函数。

看看是什么样子的
/**
* Constructs a new instance.
*/
public JVMRandom() {
this.constructed = true;
}
哦,那么没办法了,也就是说,如果我们想使用JVMRandom来构建随机数,就一定会通过无参构造函数创建对象,那么constructed就一定会是true,所以,如果你调用了setSeed方法,那么就一定会抛出上述异常。