System类实现了许多系统实用程序,其中一些已在上一节配置实用程序中介绍过,本节介绍一些其余系统实用程序。html
系统提供了几个预约义的I/O对象,这些对象在Java应用程序中很是有用,能够从命令行启动,它们实现了大多数操做系统提供的标准I/O流,以及用于输入密码的控制台对象,有关更多信息,请参阅基础I/O课程中的命令行I/O。java
在属性中,咱们研究了应用程序可使用Properties
对象来维护其配置的方式,Java平台自己使用Properties
对象来维护本身的配置,System
类维护一个Properties
对象,该对象描述当前工做环境的配置,系统属性包括有关当前用户、Java运行时的当前版本以及用于分隔文件路径名的组件的字符的信息。git
下表描述了一些最重要的系统属性。github
键 | 含义 |
---|---|
"file.separator" | 用于分隔文件路径组件的字符,这在UNIX上是“/”,在Windows上是“\” |
"java.class.path" | 用于查找包含类文件的目录和JAR存档的路径,类路径的元素由path.separator 属性中指定的特定于平台的字符分隔 |
"java.home" | Java Runtime Environment(JRE)的安装目录 |
"java.vendor" | JRE vendor名称 |
"java.vendor.url" | JRE vendor URL |
"java.version" | JRE版本号 |
"line.separator" | 操做系统用于分隔文本文件中的行的序列 |
"os.arch" | 操做系统架构 |
"os.name" | 操做系统名称 |
"path.separator" | java.class.path 中使用的路径分隔符 |
"user.dir" | 用户工做目录 |
"user.home" | 用户主目录 |
"user.name" | 用户账户名称 |
安全考虑:安全管理器能够限制对系统属性的访问,这一般是applet中的一个问题,它没法读取某些系统属性,也没法写入任何系统属性,有关访问applet中的系统属性的更多信息,请参阅“使用Java Rich Internet Applications进行更多操做”课程中的“系统属性”。
System
类有两个用于读取系统属性的方法:getProperty
和getProperties
。segmentfault
System
类有两个不一样版本的getProperty
,二者都检索参数列表中指定的属性的值,两个getProperty
方法中较简单的方法是使用单个参数,即属性键。例如,要获取path.separator
的值,请使用如下语句:api
System.getProperty("path.separator");
getProperty
方法返回包含属性值的字符串,若是该属性不存在,则此版本的getProperty
返回null
。数组
另外一个版本的getProperty
须要两个String
参数:第一个参数是查找的键,若是没法找到键或没有值,则第二个参数是要返回的默认值。例如,如下对getProperty
的调用会查找名为subliminal.message
的System
属性,这不是有效的系统属性,所以该方法不是返回null
,而是返回做为第二个参数提供的默认值:"Buy StayPuft Marshmallows!"。浏览器
System.getProperty("subliminal.message", "Buy StayPuft Marshmallows!");
System
类提供的访问属性值的最后一个方法是getProperties
方法,该方法返回一个Properties对象,该对象包含一组完整的系统属性定义。安全
要修改现有的系统属性集,请使用System.setProperties
,此方法采用已初始化为包含要设置的属性的Properties
对象,此方法使用Properties
对象表示的新集替换整个系统属性集。架构
更改系统属性可能存在危险,应谨慎处理,许多系统属性在启动后不会从新读取,而是用于提供信息,更改某些属性可能会产生意外的反作用。
下一个示例PropertiesTest建立一个Properties
对象,并从myProperties.txt初始化它。
subliminal.message=Buy StayPuft Marshmallows!
而后,PropertiesTest
使用System.setProperties
将新的Properties
对象安装为当前的系统属性集。
import java.io.FileInputStream; import java.util.Properties; public class PropertiesTest { public static void main(String[] args) throws Exception { // set up new properties object // from file "myProperties.txt" FileInputStream propFile = new FileInputStream( "myProperties.txt"); Properties p = new Properties(System.getProperties()); p.load(propFile); // set the system properties System.setProperties(p); // display new properties System.getProperties().list(System.out); } }
注意PropertiesTest
如何建立Properties
对象p
,它被用做setProperties
的参数:
Properties p = new Properties(System.getProperties());
此语句使用当前系统属性集初始化新属性对象p
,在此小应用程序的状况下,该属性是由运行时系统初始化的属性集。而后,应用程序从文件myProperties.txt
将其余属性加载到p
中,并将系统属性设置为p
。这具备将myProperties.txt
中列出的属性添加到运行时系统在启动时建立的属性集的效果,请注意,应用程序能够建立没有任何默认Properties
对象的p
,以下所示:
Properties p = new Properties();
另请注意,系统属性的值能够被覆盖!例如,若是myProperties.txt
包含如下行,则将覆盖java.vendor
系统属性:
java.vendor=Acme Software Company
一般,请注意不要覆盖系统属性。
setProperties
方法更改当前正在运行的应用程序的系统属性集,这些变化并不持久。也就是说,更改应用程序中的系统属性不会影响未来对此解释程序或任何其余应用程序的Java解释程序的调用,运行时系统每次启动时都会从新初始化系统属性,若是要保持对系统属性的更改,则应用程序必须在退出以前将值写入某个文件,并在启动时再次读取它们。
安全管理器是定义应用程序安全策略的对象,此策略指定不安全或敏感的操做,安全策略不容许的任何操做都会致使抛出SecurityException,应用程序还能够查询其安全管理器以发现容许的操做。
一般,Web applet与浏览器或Java Web Start插件提供的安全管理器一块儿运行,其余类型的应用程序一般在没有安全管理器的状况下运行,除非应用程序自己定义了安全管理器。若是没有安全管理器,则该应用程序没有安全策略,而且没有任何限制。
本节介绍应用程序如何与现有安全管理器进行交互,有关更多详细信息,包括有关如何设计安全管理器的信息,请参阅安全指南。
安全管理器是SecurityManager类型的对象,要获取对此对象的引用,请调用System.getSecurityManager
。
SecurityManager appsm = System.getSecurityManager();
若是没有安全管理器,则此方法返回null
。
一旦应用程序具备对安全管理器对象的引用,它就能够请求执行特定事务的权限,标准库中的许多类都是这样作的。例如,以退出状态终止Java虚拟机的System.exit
调用SecurityManager.checkExit
以确保当前线程具备关闭应用程序的权限。
SecurityManager
类定义了许多用于验证其余类型操做的其余方法。例如,SecurityManager.checkAccess
验证线程访问,SecurityManager.checkPropertyAccess
验证对指定属性的访问,每一个操做或一组操做都有本身的checkXXX()
方法。
此外,checkXXX()
方法集表示已受安全管理器保护的操做集,一般,应用程序没必要直接调用任何checkXXX()
方法。
在没有安全管理器的状况下,许多常规操做在使用安全管理器运行时都会抛出SecurityException
,即便在调用未记录为抛出SecurityException
的方法时也是如此,例如,请考虑如下用于读取文件的代码:
reader = new FileReader("xanadu.txt");
在缺乏安全管理器的状况下,若是xanadu.txt
存在且可读,则此语句无错误地执行,可是假设此语句插入到Web applet中,该applet一般在不容许文件输入的安全管理器下运行,可能会致使如下错误消息:
appletviewer fileApplet.html Exception in thread "AWT-EventQueue-1" java.security.AccessControlException: access denied (java.io.FilePermission characteroutput.txt write) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:323) at java.security.AccessController.checkPermission(AccessController.java:546) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.SecurityManager.checkWrite(SecurityManager.java:962) at java.io.FileOutputStream.<init>(FileOutputStream.java:169) at java.io.FileOutputStream.<init>(FileOutputStream.java:70) at java.io.FileWriter.<init>(FileWriter.java:46) ...
请注意,在这种状况下抛出的特定异常java.security.AccessControlException是SecurityException
的子类。
本节介绍了前面几节中未介绍的System
中的一些方法。
arrayCopy
方法有效地在数组之间复制数据,有关更多信息,请参阅语言基础知识课程中的数组。
currentTimeMillis和nanoTime方法可用于测量应用程序执行期间的时间间隔。要以毫秒为单位测量时间间隔,请在间隔的开始和结束时调用currentTimeMillis
两次,并从第二个返回值中减去第一个值。一样,调用nanoTime
两次测量一个纳秒的间隔。
currentTimeMillis
和nanoTime
的准确性受操做系统提供的时间服务的限制,不要假设currentTimeMillis
精确到最接近的毫秒,或者nanoTime
精确到最接近的纳秒。此外,currentTimeMillis
和nanoTime
都不该用于肯定当前时间,使用高级方法,例如 java.util.Calendar.getInstance。
exit方法使Java虚拟机关闭,并使用参数指定的整数退出状态,退出状态可用于启动应用程序的进程,按照惯例,退出状态为0表示应用程序正常终止,而任何其余值都是错误代码。、