接下来我们讲一些API涉及到的其他对象,但是我们并不是要掌握这些对象,而是要掌握查阅API的方法。
01-其他对象(System)
首先我们来看一下System。
它不能被实例化,代表着System对象没有对外提供构造函数。
接下来看它的字段摘要,都是静态的(必须是静态的,要不然怎么调用呢):
其中的out是我们最常用的。
out为什么能够调用print方法呢?其实是因为out它对应了一个对象,叫做打印流(PrintStream):
我们点进打印流这个对象中,看到有很多print方法:
这就组合成了一个输出语句,是这么来的。
接下来还有一个in,这个是可以获取键盘录入的(out是打印在控制台上是输出)。
总结一下,System:类中的方法和属性都是静态的。
out:标准输出,默认是控制台。
in:标准输入,默认是键盘。
接下来看看System的方法:
我们发现都是静态的,这里就不一个一个说了。
接下来我们说一个比较重点的方法,它可以去描述系统环境,系统环境在虚拟机启动的时候会加载一些默认的系统属性信息。
我们现在可以查阅一下,虚拟机在启动的时候到底都做了什么事情,加载了什么样的信息。
我们来看一下这个方法,getProperties:
我们看到这个方法返回一个Properties对象,而Properties是Hashtable的一个子类:
(虽然Hashtable被替代了,但是它的这个子类应用还挺广泛的)
我们在讲集合的时候之所以没有讲这个类,是因为它的应用往往和IO相关联,后面讲IO的时候会重点讲它。
但是,既然它是Hashtable的子类,我们是不是可以直接用呢?
完全可以。
因为它是Map集合中的一员,Map集合我们掌握了,那么Map集合的子类我们就都能用。
接下来我们来演示一下这个方法:
运行结果有很多,这只是一部分,都是虚拟机在启动的时候加载的一些默认的属性信息:
虚拟机在启动的时候,它会先走一遍系统的信息,获取这些系统属性信息。
那么,虚拟机在启动的时候,我们能不能自己设置一些系统的属性信息,也让它一直存在在系统级的属性当中呢?
当然可以。
接下来演示一下如何在系统中自定义一些特有信息。
我们在System中发现一个方法可以设置系统属性:
用这个方法来设置一下:
编译运行,我们在茫茫属性中找到了它:
那么下次我们启动虚拟机系统的时候,这个值它就存在,我们在其他程序中,也随时可以用System类来拿到mykey的值,这个值是可以参与运算的。
我们不获取一大堆属性,只获取单个属性也是可以的:
好,现在获取和写入我们都讲完了。
再来一个例子:
"haha"是一个并不存在的属性,所以打印出来为null:
接下来有一个问题,上面我们都是直接将属性写死了,那么能不能在虚拟机运行的过程中,动态的加载一些属性信息呢?
我们输入java命令,看一下虚拟机在启动过程中都有哪些参数值可以使用呢:
这个参数叫做设置系统属性:
我们使用这个参数重新运行一下:
就实现了在启动虚拟机的同时也加入一些参数信息。
02-其他对象(Runtime)
接下来我们说另外一个对象,还是在java.lang包中,有这么一个对象叫Runtime。
Java程序想要在某一个系统下出现一个进程并进行封装,可以通过Runtime对象来完成。它可以将应用程序和所在的系统相连接:
我们发现这个类没有构造函数,当一个类没有构造函数摘要的时候,代表着它不能够直接创建对象,可是它有方法摘要。按理说,没有构造函数,这个类里面的方法都是静态的,但是它里面的方法都是非静态的。
不让我建立对象,但是对我提供了被对象调用的方法,而这个对象就要通过一个方法来获取。这个方法一定是静态的,而且返回值类型一定为本类类型。所以我们现在找一下能够返回本类类型的静态方法:
这个对象是不需要我们建立的,应用程序一执行,它本身就创建完毕了,只要获取这个对象用就行了。
其实,这就是单例设计模式,保证了一个应用程序在内存当中只存在一个对象。
这个类中有很多方法,我们就不一个一个讲了。
这里有一个方法我们来说一下。
exec是什么意思呢?
这个exec其实是一个单词的简写,叫execute,是执行的意思。
我们经常在Windows中看到***.exe文件,它也是执行这个单词的简写。
我们现在用exec方法来启动一下扫雷:
但是这里的命令有时候也可能会出错,比如我们刚刚把扫雷的执行文件winmine.exe放在c盘中了,而且电脑中根本没有k盘,现在我们写的路径却是k盘,就会出错了。
点开exec方法,我们发现它抛出了一个输入输出异常。
所以我们偷点懒将它抛出去,但是注意不能抛IO异常,要是抛IO异常就得导IO包(IO异常在IO包中),我们懒得导包,就抛个更大的:
运行,异常了:
我们将盘符改成正确的:
再运行,扫雷启动了:
另外要注意\是转义字符,我们在写盘符的时候要写两个\\。
我们注意到,exec方法返回一个Process,就是进程:
我们点进去看一下:
注意它是抽象的,不能创建对象。
往下看,构造方法是给子类使用的:
再往下看,发现它的方法都是抽象的:
但是它又没有子类。其实,应用程序一执行,就已经产生进程了。这个程序是我们创建的吗?
并不是。
是调用了底层资源代码的。
所以它定义了一个抽象类,而没有定义子类的实现方式,因为底层在帮它做实现,而不需要我们去实现,我们也不知道怎么去调用底层的程序。
接下来我们演示一下这个方法:
我们先启动扫雷,然后再调用这个方法:
运行之后发现扫雷并没有出现,它被杀掉了,而且是秒杀。进程一启动,直接被干掉。还没怎么在任务管理器中停留,就已经被杀掉了。而图形化界面更不用说了,图形化界面还没有建立完显示出来,就已经挂掉了。(图略)
当然,我们也可以让它睡4s再杀:
这样运行的现象就是扫雷启动了,过了4秒钟又关闭了。(图略)
那我们是不是可以杀掉任务管理器中的任意进程呢?
并不是。
我们只能杀掉它启动的进程:
因为只有它启动的进程,我们才能获取到进程对象,其他的进程我们获取不到进程对象,获取不到对象就杀不掉。
接下来,你以为exec只有打开一个exe那么简单吗?
再看:
运行:
我们可以打开一个文件,只要能找到和这个文件所匹配的应用程序就OK。
03-其他对象(Date)
接下来说日期类Date,它在java.util包中存在。
看它的构造方法,好多都过时了,就剩下两个:
方法中也有很多都过时了,就剩下几个:
接下来我们玩一下。
打印现在的时间:
打印的时间看不懂怎么办呢?
我们将它按某一种格式打印出来,比如说年月日。
我们看到它有获取年、月、日的类,可是都过时了。
一般情况下,和这个类相关联的类都会写在令请参见这里:
我们点进DateFormat中看一下:
看一下它的方法:
这个挺满足我们需求的,可是这个类不能创建对象,但是我们又看到它有一个子类:
我们点进去,发现这个子类是非抽象的:
而且可以构造对象:
我们点进其中一个:
那么这个pattern是怎么用呢?传的是什么呢?
我们再往上翻,看到这里有模式的描述:
另外要注意这个子类比较特殊,属于文本方法,因为日期最终要变成文本:
我们将这个包也导入,开始使用它~
OK,按照我们的格式打印出来了:
我们再把具体的时刻也打印出来:
打印星期:
04-其他对象(Calendar)
如果我们不想格式化这个日期,而是想要单独获取其中的年、月、日该怎么做呢?
那我们单独格式化年、月、日不就可以了嘛。
比如单独格式化年:
但是有一个不方便的地方,就是它返回的是字符串,我们不能方便的给它进行加减。
很简单,Integer.ParseInt不就可以转换了嘛。
可是还是有点麻烦。那怎么办呢?
我们看到Date 类中有直接获取年的方法,它已经过时了,虽然过时了,可是它被另外的东东替代了:
用Calendar类中的get方法,只要把Calendar.YEAR字段传进来,就能够获取到年了。
我们去这个类中看一下。
我们发现它是一个抽象类:
里面有n多字段:
这是它的get方法:
因为它是抽象类,我们找它的子类:
点进去:
但是Callendar类中为我们提供了一些方法,可以获取到一个实例对象:
既然本身有获取实例的方法,那我们来试着用一下:
我们打印出了这么多信息,其实只需要其中的年份就好了:
接下来打印年月日:
但是打印出来的是0月。
给它+1:
但是有点麻烦,有没有更简单的方法呢?
还记得我们之前的查表法吗?
来一个String数组:
打印:
星期也不太对,打印出来是数字,我们把电脑的星期先暂时改成星期六:
我们也用查表法解决:
讲完了获取日期的操作,接下来讲一讲对日期进行修改的操作。
我们用set方法:
演示:
注意月份写的2就是三月哦,如果写的0就是一月。
接下来我们想把时间从当前时间上往后推五年,用add方法:
演示:
给年加:
给月加:
接下来给月减:
时间从2011年一月份回到了2010年十二月份:
同样的,给日加上天数,也从一月变到了二月:
这叫做时间上的偏移。
两个小练习的思路:
05-其他对象(Math-Random)
接下来介绍一个比较特殊的类:Math。
有两个常量值:
很多方法:
我们演示一下这个方法:
演示:
再试一个数:
给这个数前面加上负号再试一下:
总结一下:ceil返回大于指定数据的最小整数。
再看一下这个方法,floor:
演示:
总结一下:floor返回小于指定数据的最大整数。
接下来看round方法:
演示:
刚才是12.34,我们改成12.54试试:
总结:round就是四舍五入。
再看一下pow方法:
演示:
接下来说一个Math类中的重点方法,random:
这个随机数的方法要做一个重点的掌握。
演示一下:
我们发现都是0到1之间的随机数。
点进方法中看一下:
它产生的随机数是包含0不包含1的介于0到1之间的数字,是一个伪随机数。为什么叫伪随机数呢?因为它是调用算法产生的随机数,只要是通过算法产生的,那么一定有规律可循。
我们想要1都10的随机数怎么办呢?
乘以10就好啦,包含0不包含10,再加上1:
结果不太OK,因为有小数位,而且还有超过10的。
我们强转成int,把小数位舍弃掉:
左边也改成int:
这样就好啦:
如果是乘以6加1,那就是骰子啦。
但是这个方法中有这样一句话:
java.util包中也给我们提供了一个对象,叫做随机数对象:
我们只要new一个对象:
它里面也有个叫nextDouble的方法,可以生成0到1之间的随机数:
它还有一个更方便的方法,可以直接返回int型随机数:
接下来用一下:
当然,两种方式用哪种都可以。