11.4.1 认识System类
System类是一些与系统相关属性和方法的集合,而且在System类中所有的属性都是静态的,想要引用这些属性和方法,直接使用System类(不需要实例化)调用即可。
public static void exit(int status) //系统退出,如果status为非0就表示退出
public static void gc() //运行垃圾收集机制,调用的是Runtime类中的gc方法
public static long currntTimeMillis() //返回以毫秒为单位的当前日期
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) //数组复制操作
public static Properties getProperties() //取得当前系统的全部属性
public static String getProperty(String key) //根据键值取得属性的具体内容
- System类中的方法都是使用static定义的,是静态的。所以在使用时直接使用类名称就可以调用,不需要实例化一个System类的对象。 如 System.gc()。
/*
* 计算一个程序的执行时间
*/
package org.forfan06.systemdemo;
public class SystemDemo01 {
public static void main(String args[]){
long startTime = System.currentTimeMillis(); //取得开始计算之前的时间
int sum = 0;
for (int i = 0; i < 30000; i++){
sum += i;
}
long endTime = System.currentTimeMillis(); //结束计算之后的时间
System.out.println("计算所花费的时间: " + (endTime - startTime) + "毫秒");
}
}
package org.forfan06.systemdemo;
/**
* @author HE
* 列出本机的指定属性 & 本机的全部环境属性
*/
public class SystemDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
//列出指定属性
System.out.println("系统版本为: " + System.getProperty("os.name")
+ System.getProperty("os.version")
+ System.getProperty("os.arch")); //获取当前系统版本
System.out.println("系统用户为:" + System.getProperty("user.name"));
System.out.println("当前用户目录 为:" + System.getProperty("user.home"));
System.out.println("当前用户工作目录为:" + System.getProperty("user.dir"));
//列出本机的全部环境属性
System.getProperties().list(System.out);
}
}
输出结果是:
系统版本为: Windows Vista6.1x86
系统用户为:HE
当前用户目录 为:C:\Users\HE
当前用户工作目录为:D:\Workspaces\MyEclipse 10\SystemDemo
-- listing properties --
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\Users\HE\AppData\Local\Genuitec\Co...
java.vm.version=11.3-b02
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
需要注意的是一下两个属性:
- 文件默认编码: file.encoding=GBK
- 文件分隔符: file.separator=\
11.4.2 垃圾对象的回收
Java中有垃圾的自动收集机制,可以不定期地释放Java中的垃圾空间,而且在前面讲过的Runtime类时也了解了如何进行垃圾空间的释放。在System类中也有一个gc()方法,此方法也可以进行垃圾的收集;而且此方法实际上是对Runtime类中的gc()方法的封装,功能与其类似。
但是此处讲解的是如何对一个对象进行回收!!!一个对象如果不再被任何栈内存所引用,那么此对象就可以称为垃圾对象,等待被回收。时间上,等待的时间是不确定的,所以可以直接调用System.gc()方法进行垃圾的回收。
- 在实际的开发中,垃圾内存(垃圾收集)的释放基本上都是由系统自动完成的,除非特殊的情况,一般都很少直接去调用gc()方法。
- 手工调用垃圾收集的方法:1,System.gc(); 2, Runtime.getRuntime().gc();
但是,如果在一个对象被回收之前要进行某些操作该怎么办呢??实际上在Object类中有一个 finalize()方法,此方法的定义如下:
protected void finalize() throws Throwable
一个子类只需要覆写此方法即可在释放对象前进行某些操作。
package org.forfan06.systemdemo;
/**
* @author HE
* 观察对象的释放!!!
*/
class Person{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
public String toString(){
return "姓名:" + this.name + ",年龄:" + this.age;
}
public void finalize() throws Throwable{ //对象释放空间时默认调用此方法
System.out.println("对象被释放 -->" + this); //直接打印对象调用toString
}
}
public class SystemDemo04 {
/**
* @param args
*/
public static void main(String[] args) {
Person per = new Person("张三", 27);
per = null; //断开引用,释放空间
System.gc(); //强制性释放空间
}
}
运行结果:
对象被释放 -->姓名:张三,年龄:27
以上程序中强制调用了释放空间的方法,而且在对象被释放前调用了finalize()方法。如果在finalize()方法中出现了异常,则程序并不会受影响,会继续执行。
- 在finalize()方法上可以发现抛出的异常并不是常见的Exception,而是使用了Throwable进行抛出的异常,所以在调用此方法时不一定只会在程序运行中产生错误,也有可能产生JVM
11.4.3 对象的生命周期
对象的生命周期,如图所示:
一个类家贼后进行初始化,然后就可以进行对象的实例化,对象实例化时会调用构造方法完成,当一个对象不再使用时就要等待被垃圾收集,然后对象终结,最终被程序卸载。
11.5 日期操作类
在程序的开发中经常会遇到日期类型的操作,在Java中对于日期的操作也提供了良好的支持,主要使用java.util包中的Date、Calendar、以及java.text包中的 SimpleDateFormat。
11.5.1 Date类
Date类是一个较为简单的操作类,在使用中直接使用java.util.Date类的构造方法并进行输出就可以得到一个完整的日期,构造方法定义如下:
<span style="color:#ff0000;">public Date()</span>
/*
* 得到当前系统日期
*/
package org.forfan06.datedemo;
import java.util.Date;
public class DateDemo01{
public static void main(String args[]){
Date date = new Date(); //实例化Date类对象
System.out.println("当前日期是:" + date); //输出日期
}
}
运行结果是:
当前日期是:Tue Jul 15 10:17:17 CST 2014
从上面的输出结果来看,虽然得到了系统的当前日期,但是此日期的显示格式并不符合平常看到的格式;而且时间也不能精确到毫秒级。要想按照用户自己的格式显示时间,可以使用Calender类完成操作!!!
- 虽然使用Date显示的日期格式并不符合用户的要求,但是从实际的角度来看Date类的使用频率也是很高的,因为只要使用格式化的方式就可以直接将一个日期格式按照用户所需要的方式进行显示!!!!
11.5.2 Calendar类
Calendar类可以将取得的时间精确到毫秒。但是,这个类本身是一个抽象类! 如果想要使用一个抽象类,则必须依靠对象的多态性,通过子类进行父类的实例化操作。
Calendar类的子类是GregorianCalendar类。
在Calendar类中提供了下面的部分常量,分别表示日期的各个数字:
public static final int YEAR //int 取得年
public static final int MONTH //int 取得月
public static final int DAY_OF_MONTH //int 取得日
public static final int HOUR_OF_DAY //int 取得小时,24小时制
public static final int MINUTE //int 取得分
public static final int SECOND //int 取得秒
public static final int MILLISECOND //int 取得毫秒
Calendar类中还提供了一些常用的方法,如下所示:
public static Calendar getInstance() //根据默认的时区实例化对象
public boolean after(Object when) //判断一个日期是否在指定日期之后
public boolean before(Object when) //判断一个日期是否在指定日期之前
public int get(int field) //返回给定日历字段的值
范例:获取系统的当前日期信息
package org.forfan06.datedemo;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateDemo02{
public static void main(String args[]){
Calendar calendar = null; //declare 一个Calendar对象
calendar = new GregorianCalendar(); //通过子类为Calendar实例化对象
System.out.println("年:" + calendar.get(Calendar.YEAR));
System.out.println("月:" + (calendar.get(Calendar.MONTH) + 1)); //MONTH要加1才能得到正确的月份。因为GregorianCalendar中第一个月是JANUARY,它为0!
System.out.println("日:" + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时:" + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分:" + calendar.get(Calendar.MINUTE));
System.out.println("秒:" + calendar.get(Calendar.SECOND));
System.out.println("毫秒:" + calendar.get(Calendar.MILLISECOND));
System.out.println("星期∶" + (calendar.get(Calendar.DAY_OF_WEEK) - 1)); //DAY_OF_WEEK要减一后才能得到正确的星期。
}
}
上面程序通过GregorianCalendar子类实例化Calendar类对象,然后通过Calendar类中的各种常量及方法取得系统的当前日期信息。
但是,如果按照以上的方式取得,代码会比较复杂,所以JAVA中又提供了其他日期的类。
补充: Calendar.MONTH需要加一、Calendar.DAY_OF_WEEK需要减一的原因
- 在获取月份时,Calendar.MONTH需要加一的原因: java中的月份遵循了罗马历中的规则, 当时一年中的月份数量是不固定的,第一个月是JANUARY;而在java中Calendar.MONTH返回的数值其实是当前月 距离第一个月有多少个月份的数字,JANUARY在java中返回‘ 0 ’,所以我们需要 +1
- 获取星期几, Calendar.DAY_OF_WEEK 需要减一的原因: java中calendar.DAY_OF_WEEK其实表示, 一周中的第几天,所以它会受到第一天是星期几的影响;有些地区以星期日作为一周的第一天,而有些地区以星期一作为一周的第一天,这2种情况是需要区分的。
- (1) 星期日作为一周的第一天: DAY_OF_WEEK的返回值: 1 --> SUN; 2 --> MON; 3 --> TUE; 4 --> WED; 5 --> THU; 6 --> FRI; 7 --> SAT;
- (2) 星期一作为一周的第一天: DAY_OF_WEEK的返回值: 1 --> MON; 2 --> TUE; 3 --> WED; 4 --> THU; 5 --> FRI; 6 --> SAT; 7 --> SUN;
- 所以Calendar.DAY_OF_WEEK需要根据本地化设置的不同而确定是否需要 -1
- java中设置不同地区的输出可以使用Locale.setDefault(Locale.地区名)来实现。
- 获取日期时Calendar.DAY_OF_MONTH不需要特殊的操作,它直接返回一个月中的第几天
11.5.3 DateFormat类
在java.util.Date类中实际上取得的时间是一个非常正确的时间。但是因为其显示的格式不理想,所以无法负荷中国人的习惯要求,那么实际上此时就可以为此类进行格式化操作,变为符合中国人习惯的日期格式。
DateFormat类与MessageFormat类都是属于Format类的子类,专门用于格式化数据使用。
DateFormat类的定义如下:
<span style="color:#ff0000;">public abstract class DateFormat extends Format</span>
******************DateFormat类是一个抽象类,所以肯定无法直接实例化。但是在此抽象类中提供了一个静态方法,可以直接取得本类的实例*************************
此类的常用方法有如下几个:
public static final DateFormat getDateInstance() //得到默认的对象
public static final DateFormat getDateInstance(int style, Locale aLocale) //根据Locale得到对象
public static final DateFormat getDateTimeInstance() //得到日期时间对象
public static final DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale) //根据Locale得到日期时间对象
以上4个方法可以构造DateFormat类的对象,但是这些方法需要传递若干个参数,这些参数表示日期地域或者日期的显示形式。
下面通过几个程序来了解DateFormat类的操作:
(1) DateFormat类的默认显示
/*
* 观察DateFormat类中的默认操作
*/
package org.forfan06.datedemo;
import java.text.DateFormat;
import java.util.Date;
public class DateDemo03{
public static void main(String args[]){
DateFormat df1 = null; //声明两个DateFormat类的对象
DateFormat df2 = null;
df1 = DateFormat.getDateInstance(); //取得日期
df2 = DateFormat.getDateTimeInstance(); //取得日期时间
System.out.println("Date: " + df1.format(new Date())); //格式化日期
System.out.println("DateTime: " + df2.format(new Date()));
}
}
运行结果:
-------------------------------------------------
Date: Jul 15, 2014
DateTime: Jul 15, 2014 1:26:39 PM
-------------------------------------------------
(2)要想其显示比较合理的中文格式,必须在构造DateFormat类的对象时传递若干参数。
/*
* 指定显示的风格
*/
package org.forfan06.datedemo;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
public class DateDemo04{
public static void main(String args[]){
DateFormat df1 = null; //声明两个DateFormat类的对象
DateFormat df2 = null;
df1 = DateFormat.getDateInstance(DateFormat.YEAR_FIELD, new Locale("zh", "CN")); //取得日期
df2 = DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD, DateFormat.ERA_FIELD, new Locale("zh", "CN")); //取得日期时间
System.out.println("Date: " + df1.format(new Date())); //格式化日期
System.out.println("DateTime: " + df2.format(new Date()));
}
}
运行结果:
-------------------------------------------------
Date: 2014年7月15日
DateTime: 2014年7月15日 下午01时31分01秒 CST
-------------------------------------------------
(3)程序DateDemo04已经将日期时间显示格式化,但是其格式是默认的时间显示格式; 此时若想得到用户自定义的日期显示格式,则必须通过DateFormat的子类SimpleDateFormat类来完成
11.5.4 SimpleDateFormat类
在实际项目开发中,会经常讲一个日期格式转换为另外一种日期格式。想要实现2014-07-15 14:34:27.567 --> 2014年7月15日14时34分27秒567毫秒 两种格式间的转换就需要使用java.text包中的SimpleDateFormat类。
首先必须先定义出一个完整的日期转化模板,在模板中通过特定的日期标记可以将一个日期格式中的日期数字提取出来,日期格式化模板标价如下表:
=======================================================================
标记 描述
y --------------------->> 年;年份是4位数字,所以需要使用yyyy表示
M --------------------->> 年中的月份;月份时两位数字,所以需要使用MM表示
d --------------------->> 月中的天数; 天数是两位数字,用 dd 表示
H --------------------->> 一天中的小时数(24小时); 小时是两位数字,用 HH 表示
m --------------------->> 小时中的分钟数; 分钟是两位数字, 用 mm 表示
s --------------------->> 分钟中的秒数; 秒数是两位数字, 用 ss 表示
S --------------------->> 毫秒数; 毫秒数是三位数字,用 SSS 表示
=======================================================================
此外,还需要SimpleDateFormat类中的方法才可以完成, SimpleDateFormat类中常用的方法如下:
=======================================================================
public SimpleDateFormat(String pattern) //通过一个指定的模板构造对象
public Date parse(String source) throws ParseException //将一个包含日期的字符串变为Date类型的数据
public final String format(Date date) //将一个Date类型按照指定格式变为String类型
=======================================================================
范例: 格式化日期操作
/*
* 格式化日期操作
*/
package org.forfan06.datedemo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo05{
public static void main(String args[]){
String strDate = "2014-07-15 14:34:27.567"; //定义日期时间的字符串
String pat1 = "yyyy-MM-dd HH:mm:ss.SSS"; //准备第1个模板,从字符串中提取日期数字
String pat2 = "yyyy年MM月dd日HH时mm分ss秒SSS毫秒"; //准备第2个模板,将提取后的日期数字变为指定的格式
SimpleDateFormat sdf1 = new SimpleDateFormat(pat1); //实例化模板对象
SimpleDateFormat sdf2 = new SimpleDateFormat(pat2); //实例化模板对象
Date d = null;
try{
d = sdf1.parse(strDate); //将给定字符串中的日期提取出来
}catch(ParseException e){ //如果提供的字符串格式有错误,则进行异常处理
e.printStackTrace();
}
System.out.println(sdf2.format(d)); //将日期变为新的格式
}
}
运行结果:
-------------------------------------------------
2014年07月15日14时34分27秒567毫秒
-------------------------------------------------
上面程序中,首先使用第1个模板将字符串中表示的日期数字提取出来,然后再使用第2个模板将这些日期数字重新转换为新的格式表示!!!!
- SimpleDateFormat类经常用于将String变为Date类型数据。 在实际开发中,用户所输入的各个数据都是以String的方式进行接收的,所以此时为了可以正确地将String变为Date类型数据,就需要依靠SimpleDateFormat类来完成!!!
范例:将String类型数据变为Date类型数据
/*
* String类型数据转换为Date类型数据
*/
package org.forfan06.datedemo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo06{
public static void main(String args[]){
String strDate = "2014-07-15 14:34:27.567"; //定义日期时间的字符串
String pat1 = "yyyy-MM-dd HH:mm:ss.SSS"; //
SimpleDateFormat sdf = new SimpleDateFormat(pat1); //
Date d = null;
try{
d = sdf.parse(strDate);
}catch(ParseException e){
e.printStackTrace();
}
System.out.println(d);
}
}
运行结果:
-------------------------------------------------
Tue Jul 15 14:34:27 CST 2014
-------------------------------------------------
- String类型数据向Date类型数据的转型操作,在JAVA数据库编程时会经常使用到!!!!
11.5.5 实例操作 -- 取得完整日期
(1)实现一: 基于Calendar类
(2)实现二: 基于SimpleDateFormat类
/*
* 取得系统的当前时间和时间戳
*/
package org.forfan06.datedemo;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDemo07{
public static void main(String args[]){
DateTime dt = new DateTime();
System.out.println("系统日期是:" + dt.getDate());
System.out.println("中文日期是:" + dt.getDateCN());
System.out.println("时间戳是:" + dt.getTimeStamp());
}
}
class DateTime{
//声明日期格式化操作对象,直接对new Date()进行实例化
private SimpleDateFormat sdf = null;
//得到完整的日期,格式为:yyyy-MM-dd HH:mm:ss.SSS
public String getDate(){
this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
return this.sdf.format(new Date());
}
//得到完整的日期,格式为:yyyy年MM月dd日HH时mm分ss秒SSS毫秒
public String getDateCN(){
this.sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒SSS毫秒");
return this.sdf.format(new Date());
}
//
public String getTimeStamp(){
this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return this.sdf.format(new Date());
}
}
运行结果:
-------------------------------------------------
系统日期是:2014-07-15 15:29:23.783
中文日期是:2014年07月15日15时29分23秒786毫秒
时间戳是:20140715152923787
-------------------------------------------------