上一篇文章,我们介绍了几种随机数的生成策略。
那么接下来,我们来分析一下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方法,那么就一定会抛出上述异常。
原文始发于微信公众号(步尔斯特):JVMRandom不可设置种子|问题追溯|源码追溯
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/35805.html