- 浏览: 254200 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
aquarion:
非常感谢,解决了我的问题
Perspective 自定义设置扩展点 -
zheng_zhen:
好文章,进一步问您一下,请问自己实现的run/debug如何能 ...
【原创】Eclipse Launcher (Run/Debug As 菜单扩展)实现 -
salever:
mwdnjupt 写道http://www.xeclipse. ...
浅析OSGI的bundle依赖 -
mwdnjupt:
http://www.xeclipse.com/?p=1165 ...
浅析OSGI的bundle依赖 -
Tom.X:
插件化、模块化应遵循高内聚、低耦合的原则,尽量不要在各bund ...
浅析OSGI的bundle依赖
本文同步发表在 http://www.xeclipse.com/?p=1300
最近又抽空看了一下java的System类,发现了一些有意思的地方,做一个简单的整理吧,免得忘记了。
public final class System extends Object
System 类包含一些有用的类字段和方法。它不能被实例化。
在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
以上源自JDK 6.0的官方API说明,这里分享一下个人的理解。
这个类有几个比较重要的方法,比如
static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) static long currentTimeMillis() static Map<String,String> getenv() static Properties getProperties() static void loadLibrary(String libname) static long nanoTime()
下面一一讲解一下:
计时
currentTimeMillis() 返回以毫秒为单位的当前时间。
nanoTime() 返回最准确的可用系统计时器的当前值,以毫微秒为单位。
这2个方法的区别很大,并非仅仅只是时间精度的区别。currentTimeMillis() 返回当前时间,而nanoTime() 只是返回一个毫微妙级别的数字,并非代表当前的系统时间。但是可以用返回的结果查进行经确定时。
long nanoTime1 = System.nanoTime(); long timeMillis1 = System.currentTimeMillis(); System.out.println("System.nanoTime():" + nanoTime1); System.out.println("System.currentTimeMillis(): " + timeMillis1);
输出结果:
System.nanoTime():117701429470021 System.currentTimeMillis(): 1343123446809
并非只是差了10^6次方。
下面会讲到如何用nanoTime来进行准备计时。
数据复制
arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束。
这是一个很常用的方法,平时用到过,但是没怎么注意它的实现,结果上次就遇到一个小尴尬。按照一般来说,Java中的数组复制有2种情况,浅复制和深复制。前者就不必再赘述了,后者其实就是对元素的单独复制,2个数组之间不存在引用关系。
int size = 100000; int[] sources = new int[size]; int[] destination = new int[size]; for (int index = 0; index < size; index++) { destination[index] = sources[index]; } long nanoTime2 = System.nanoTime(); long timeMillis2 = System.currentTimeMillis(); System.out.println("User array copy takes : " + (nanoTime2 - nanoTime1) + " in ns."); System.out.println("User array copy takes : " + (timeMillis2 - timeMillis1) + " in ms"); System.arraycopy(sources, 0, destination, 0, size); long nanoTime3 = System.nanoTime(); long timeMillis3 = System.currentTimeMillis(); System.out.println("System array copy takes : " + (nanoTime3 - nanoTime2) + " in ns."); System.out.println("System array copy takes : " + (timeMillis3 - timeMillis2) + " in ms");
这里对100000个整型数组进行复制,分别采用数组复制和System的复制,看看结果:
User array copy takes : 2470705 in ns. User array copy takes : 2 in ms System array copy takes : 148977 in ns. System array copy takes : 1 in ms
这里System的arrayCopy几乎要快一倍。
换几个值测试一下:
10000(1万)的情况
User array copy takes : 634974 in ns. User array copy takes : 1 in ms System array copy takes : 158578 in ns. System array copy takes : 0 in ms
1000000(1百万)的情况
User array copy takes : 13381801 in ns. User array copy takes : 13 in ms System array copy takes : 1432499 in ns. System array copy takes : 2 in ms
100000000(1千万)
User array copy takes : 72962115 in ns. User array copy takes : 73 in ms System array copy takes : 12106224 in ns. System array copy takes : 12 in ms
对比一下知道了,System的arrayCopy要快很多。
为什么呢,看看方法的实现去:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
JNI实现,我觉得应该是使用了指针的移动进行计算的。不确定。。。
获取系统信息
getProperties() 确定当前的系统属性。
getenv() 返回一个不能修改的当前系统环境的字符串映射视图。
这里的2个方法都是获取系统信息的,一个是系统的一些属性信息,一个是系统环境变量。不过对于系统属性来说,Java提供了在当前JVM生命周期内临时修改的方法,
setProperty(String key, String value) 设置指定键指示的系统属性。
先看看getProperties():
java.version |
Java 运行时环境版本 |
java.vendor |
Java 运行时环境供应商 |
java.vendor.url |
Java 供应商的 URL |
java.home |
Java 安装目录 |
java.vm.specification.version |
Java 虚拟机规范版本 |
java.vm.specification.vendor |
Java 虚拟机规范供应商 |
java.vm.specification.name |
Java 虚拟机规范名称 |
java.vm.version |
Java 虚拟机实现版本 |
java.vm.vendor |
Java 虚拟机实现供应商 |
java.vm.name |
Java 虚拟机实现名称 |
java.specification.version |
Java 运行时环境规范版本 |
java.specification.vendor |
Java 运行时环境规范供应商 |
java.specification.name |
Java 运行时环境规范名称 |
java.class.version |
Java 类格式版本号 |
java.class.path |
Java 类路径 |
java.library.path |
加载库时搜索的路径列表 |
java.io.tmpdir |
默认的临时文件路径 |
java.compiler |
要使用的 JIT 编译器的名称 |
java.ext.dirs |
一个或多个扩展目录的路径 |
os.name |
操作系统的名称 |
os.arch |
操作系统的架构 |
os.version |
操作系统的版本 |
file.separator |
文件分隔符(在 UNIX 系统中是“/”) |
path.separator |
路径分隔符(在 UNIX 系统中是“:”) |
line.separator |
行分隔符(在 UNIX 系统中是“/n”) |
user.name |
用户的账户名称 |
user.home |
用户的主目录 |
user.dir |
用户的当前工作目录 |
输出地结果为:写道
, java.vm.specification.vendor=Sun Microsystems Inc., user.variant=, os.name=Windows 7, sun.jnu.encoding=GBK, java.library.path=C:\Java\jdk1.6.0_17\bin;.;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;F:\IBM\WebSphere MQ\Java\lib;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Java\jdk1.6.0_17\bin;D:\Program Files\TortoiseSVN\bin;D:\library\apache-maven-3.0.3\bin;F:\IBM\WebSphere MQ\bin;F:\IBM\WebSphere MQ\tools\c\samples\bin;C:\Program Files\MySQL\MySQL Server 5.1\bin;D:\library\apache-ant-1.8.2/bin;C:\Program Files\Bitvise Tunnelier, java.specification.name=Java Platform API Specification, java.class.version=50.0, sun.management.compiler=HotSpot Client Compiler, os.version=6.1, user.home=C:\Users\LiXP, user.timezone=, java.awt.printerjob=sun.awt.windows.WPrinterJob, file.encoding=UTF-8, java.specification.version=1.6, java.class.path=E:\workspace\common_ws\org.salever.j2se.common\bin;E:\workspace\common_ws\org.salever.j2se.common\lib\activation.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\commons-email-1.2.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\mail.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\jxl.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\comm.jar;D:\Program Files\eclipse\plugins\org.junit_4.8.1.v4_8_1_v20100427-1100\junit.jar;D:\Program Files\eclipse\plugins\org.hamcrest.core_1.1.0.v20090501071000.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\jacob.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\commons-collections-3.2.1.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\commons-lang-2.4.jar;E:\workspace\common_ws\org.salever.j2se.common\lib\velocity-1.6.4.jar, user.name=LiXP, java.vm.specification.version=1.0, java.home=C:\Java\jdk1.6.0_17\jre, sun.arch.data.model=32, user.language=en, java.specification.vendor=Sun Microsystems Inc., awt.toolkit=sun.awt.windows.WToolkit, java.vm.info=mixed mode, java.version=1.6.0_17, java.ext.dirs=C:\Java\jdk1.6.0_17\jre\lib\ext;C:\Windows\Sun\Java\lib\ext, sun.boot.class.path=C:\Java\jdk1.6.0_17\lib\tools.jar;C:\Java\jdk1.6.0_17\jre\lib\resources.jar;C:\Java\jdk1.6.0_17\jre\lib\rt.jar;C:\Java\jdk1.6.0_17\jre\lib\jsse.jar;C:\Java\jdk1.6.0_17\jre\lib\jce.jar;C:\Java\jdk1.6.0_17\jre\lib\charsets.jar, java.vendor=Sun Microsystems Inc., file.separator=\, java.vendor.url.bug=http://java.sun.com/cgi-bin/bugreport.cgi, sun.io.unicode.encoding=UnicodeLittle, sun.cpu.endian=little, sun.desktop=windows, sun.cpu.isalist=pentium_pro+mmx pentium_pro pentium+mmx pentium i486 i386 i86}
这里还有一个实时设置属性的方法,其实在Java程序启动的时候,设置的参数-D也有这个功能。
先看看一个简单的使用:
System.setProperty("user.home", "c:/"); property = System.getProperty("user.home"); System.out.println("user.home:" + property); property = System.getProperty("user.dir"); System.out.println("user.dir:" + property); System.setProperty("user.dir", "c:/"); property = System.getProperty("user.dir"); System.out.println("user.dir:" + property); property = System.getProperty("user.newArg"); System.out.println("user.newArg:" + property); System.setProperty("user.newArg", "c:/"); property = System.getProperty("user.newArg"); System.out.println("user.newArg:" + property);
其中user.home user.dir都是已知属性,而user.newArg则是新创建的,看看打印的输出:
user.home:C:\Users\LiXP user.home:c:/ user.dir:E:\workspace\common_ws\org.salever.j2se.common user.dir:c:/ user.newArg:null user.newArg:c:/
这里将user.home和user.dir都设置为c:/,然后在user.newArg被设置为新的值c:/
类似,如果在JVM启动参数加上:写道
打印的结果为:user.home:d:/
user.home:c:/ user.dir:d:/ user.dir:c:/ user.newArg:helloworld user.newArg:c:/
关于-D开始的参数,参考上面得列表。
动态加载DLL类库
load(String filename) 从作为动态库的本地文件系统中以指定的文件名加载代码文件。
loadLibrary(String libname) 加载由 libname 参数指定的系统库。
这里主要用于JNI的使用,动态的加载DLL或者其他文件,关于JNI这里暂不讲述。只是提一下。System本身的很多方法都是通过JNI调用的本地方法,可想而知,JVM的实现必须要包含这些。
发表评论
-
Java 技能树
2016-07-25 18:58 788java技能树 -
Java看书笔记
2014-08-07 17:15 722这一篇专用于一些日常的Java读书笔记 先写一点关 ... -
XStream和Jackson的使用优化
2012-12-17 11:09 0marker一下,需要研究一下这2种lib的使用方式。 -
ArrayList与LinkedList的简单比较
2012-07-27 11:07 1532本文同步发表在http://www.xeclipse.com/ ... -
Linux/Unix下JFreeChart的NoClassDefFoundError问题
2012-07-04 14:51 1667最近遇到这样一个问题,使用JFreechart 1.0.13开 ... -
【转】常见的开源协议
2011-08-12 15:47 511Mozilla Public License ... -
【转】JDK发布版本时间以及代号
2011-06-20 14:02 1553已发行的版本: 版本号 名称 中文名 发布日期 ... -
最近的apache学习计划
2011-06-09 11:58 1231最近可能会要做一些apache相关的学习和开发工作,有一些pr ... -
Object类wait,notify,notifyAll的使用
2011-05-06 11:02 1466这三个方法是java的基础类Object中定义的。 w ... -
Java nio 整理整理
2011-02-25 17:17 1103看了看Java的nio类库,整理一下思路。 1,Buf ... -
Java 内存的那些事
2011-02-22 10:38 5009虽然Java屏蔽了一下内存 ... -
一些有用的Web Service 地址
2011-02-11 11:11 2211这里记录一下比较有用的Web Service 地址,可能会有用 ... -
【Java】利用HTML生成PDF之问题整理
2011-01-06 14:38 3927首先,技术为apache 的FOP ... -
【转】如何在java程序中设置文件为“隐藏”属性
2010-10-19 10:55 1599引自http://linshiquan.iteye.com/b ... -
【转】字符,字节和编码
2010-10-18 10:09 1185引言 “字符与编码” ... -
Effective Java 第2版 笔记
2010-08-18 15:45 1849Item 1;Consider static factoriy ... -
Java, 那些美妙的书籍
2010-08-10 15:39 7214整理一下最近看过或者比较有兴趣的Java书籍,以供大家参考 ... -
Object的equals()重写
2010-08-10 14:49 1543JDK1.6 API写道 public boolean e ... -
Object的equals()与hashCode()的关系
2010-08-10 14:37 0笔者在以前Java项目中使用findbugs工具时,经常遇到一 ... -
学习JVM 之 class文件校验器
2010-07-21 11:29 1973JVM中的class文件校 ...
相关推荐
### Java学习教程:Java中Number类浅析 #### 一、概述 在Java语言中,`Number`类作为所有基本数值类型的包装类的基础类,它提供了一系列用于处理数值的方法。这些包装类包括`Integer`、`Long`、`Byte`、`Double`、...
- **基于接口的动态代理**:使用 `java.lang.reflect.Proxy` 类和 `java.lang.reflect.InvocationHandler` 接口来实现。 - **基于类的动态代理(CGLIB)**:使用第三方库 CGLIB 来实现代理,适用于无法使用基于接口...
### Java中main()方法浅析 #### 一、概述 在Java编程语言中,`main()`方法具有特殊的意义,它是所有Java应用程序的起点。当Java虚拟机(JVM)启动并加载了一个包含`main()`方法的类时,它会自动调用这个方法来开始...
也可以包含 Java.lang.Object 里的 public 方法,因为任何一个类都继承 Object 类,包含了来自 java.lang.Object 里对这些抽象方法的实现,也不属于抽象方法。 Java 8 内置函数式接口: * 四大核心函数式接口:...
在Java中,可以使用ArrayList或ArrayUtils(Apache Commons Lang库)来合并数组。ArrayList是一个动态数组,可以添加、删除元素。以下是使用ArrayList合并两个整数数组的示例: ```java import java.util.ArrayList...
例如,`java.lang.String`类就是`final`的,防止了对字符串操作的不必要的复杂性。 2. **final修饰方法**: `final`方法不能被子类重写,这保证了在继承链中的特定实现。这通常用于确保某些方法的行为在任何时候都...
Java中的`static`关键字是Java语言中的一个重要特性,它用于定义类级别的成员,包括变量、方法、块和内部类。本文将深入解析`static`关键字的五个主要用途:静态成员变量、静态方法、静态初始化块、静态内部类以及...
Exception in thread "main" java.lang.ArithmeticException: / by zero at com.becoda.bkms.bus.basics.web.Test2.test(Test2.java:15) at com.becoda.bkms.bus.basics.web.Test2.main(Test2.java:5) 可以看到,...
当我们使用`enum`定义一个枚举类型时,实际上创建了一个继承自`java.lang.Enum`的类。例如: ```java public enum OpConstants { TURN_LEFT, TURN_RIGHT, SHOOT } ``` 这里,`OpConstants`就是一个枚举类型,...
例如,`java.lang.Object` 类就是 `final` 的,因此不能有任何子类。 - **final 修饰变量**:`final` 变量是一个常量,一旦赋值后就不能再改变。这可以是类级别的静态变量或实例变量,也可以是局部变量。例如: ``...
在Java代码中,我们通常会在类的静态代码块中调用`System.loadLibrary()`方法,如`System.loadLibrary("media_jni");`,这会指示VM在运行时加载指定的动态链接库(如libmedia_jni.so)。这个过程发生在Java类被首次...