1700440812
1700440813
上面使用了Random的有参构造,运行结果如下:
1700440814
1700440815
第1次:-498702880
1700440816
1700440817
第2次:-858606152
1700440818
1700440819
第3次:1942818232
1700440820
1700440821
计算机不同输出的随机数也不同,但是有一点是相同的:在同一台机器上,甭管运行多少次,所打印的随机数都是相同的,也就是说第一次运行,会打印出这三个随机数,第二次运行还是打印出这三个随机数,只要是在同一台硬件机器上,就永远都会打印出相同的随机数,似乎随机数不随机了,问题何在?
1700440822
1700440823
那是因为产生随机数的种子被固定了,在Java中,随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:
1700440824
1700440825
种子不同,产生不同的随机数。
1700440826
1700440827
种子相同,即使实例不同也产生相同的随机数。
1700440828
1700440829
看完上面两个规则,我们再来看这个例子,会发现问题就出在有参构造上,Random类的默认种子(无参构造)是System.nanoTime()的返回值(JDK 1.5版本以前默认种子是System.currentTimeMillis()的返回值),注意这个值是距离某一个固定时间点的纳秒数,不同的操作系统和硬件有不同的固定时间点,也就是说不同的操作系统其纳秒值是不同的,而同一个操作系统纳秒值也会不同,随机数自然也就不同了。(顺便说下,System.nanoTime不能用于计算日期,那是因为“固定”的时间点是不确定的,纳秒值甚至可能是负值,这点与System.currentTimeMillis不同。)
1700440830
1700440831
new Random(1000)显式地设置了随机种子为1000,运行多次,虽然实例不同,但都会获得相同的三个随机数。所以,除非必要,否则不要设置随机种子。
1700440832
1700440833
顺便提一下,在Java中有两种方法可以获得不同的随机数:通过java.util.Random类获得随机数的原理和Math.random方法相同,Math.random()方法也是通过生成一个Random类的实例,然后委托nextDouble()方法的,两者是殊途同归,没有差别。
1700440834
1700440835
注意 若非必要,不要设置随机数种子。
1700440836
1700440837
1700440838
1700440839
1700440841
编写高质量代码:改善Java程序的151个建议 第3章 类、对象及方法
1700440842
1700440843
书读得多而不思考,你会觉得自己知道的很多。
1700440844
1700440845
书读得多而思考,你会觉得自己不懂的越来越多。
1700440846
1700440847
——伏尔泰
1700440848
1700440849
在面向对象编程(Object-Oriented Programming, OOP)的世界里,类和对象是真实世界的描述工具,方法是行为和动作的展示形式,封装、继承、多态则是其多姿多彩的主要实现方式,如此,OOP才会像现在这样繁荣昌盛、欣欣向荣。
1700440850
1700440851
本章主要讲述关于Java类、对象、方法的种种规则、限制及建议,让读者在面向对象编程的世界中走得更远,飞得更高。
1700440852
1700440853
1700440854
1700440855
1700440857
编写高质量代码:改善Java程序的151个建议 建议31:在接口中不要存在实现代码
1700440858
1700440859
看到这样的标题读者可能会纳闷:接口中有实现代码?这怎么可能呢?确实,接口中可以声明常量,声明抽象方法,也可以继承父接口,但就是不能有具体实现,因为接口是一种契约(Contract),是一种框架性协议,这表明它的实现类都是同一种类型,或者是具备相似特征的一个集合体。对于一般程序,接口确实没有任何实现,但是在那些特殊的程序中就例外了,阅读如下代码:
1700440860
1700440861
public class Client{
[
上一页 ]
[ :1.700440812e+09 ]
[
下一页 ]