文章目录
1、运行时类:Runtime类
public class Runtime extends Object
0:类的引入及其描述
运行时类再java.lang包下,不需要导包。描述说:每一个Java应用程序都有一个Runtime实例,使应用程序与其运行环境相连接。可以通过 getRuntime()
方法获取当前的运行时对象。注意:Java应用程序是不可以创建自己的Runtime类实例。
A:成员变量【Field Summary】
没有
B:构造方法【Constructor Summary】
仅仅存在一个私有构造private Runtime() { }
C:成员方法【Method Summary】
仅仅存在一个可用的静态方法 getRuntime
,用于获取应用程序的运行时对象。其它的非静态方法都依赖于这个运行时对象。
-
a、
public static Runtime getRuntime()
返回与当前Java应用程序有关的运行时对象。Runtime类的大多数方法实例方法,必须根据当前的运行时对象对其进行调用。 -
b、
public void gc()
运行垃圾回收器。调用此方法意味着 Java 虚拟机做了一些努力来回收未用对象,以便能够快速地重用这些对象当前占用的内存。当控制从方法调用中返回时,虚拟机已经尽最大努力回收了所有丢弃的对象。 名称 gc 代表“garbage collection”。虚拟机根据需要在单独的线程中自动执行回收过程,甚至不用显式调用 gc 方法。自动垃圾回收机制
。方法System.gc()
是调用此方法的一种传统而便捷的方式。 -
c、
public void exit(int status)
通过启动虚拟机的关闭序列,终止当前正在运行的Java虚拟机。此方法从不正常返回。可以将变量status作为一个状态码,根据惯例:status 为 0 表示正常终止;非 0 状态值则是 非正常终止。System.exit()
方法就是该方法传统而便捷的方式。 -
d、
public Process exec(String command)
调用系统进程
示例:调用常用的系统附件
package com.rupeng.runtime;
import java.io.IOException;
public class Demo
{
public static void main(String[] args) throws IOException
{
Runtime currentRuntime = Runtime.getRuntime();
// currentRuntime.exec("calc");
// currentRuntime.exec("xjad");
// currentRuntime.exec("notepad");
// currentRuntime.exec("mspaint");
currentRuntime.exec("shutdown -s -t 10000");
currentRuntime.exec("shutdown -a");
}
}
D:类的源码
饿汉式的单例模式(singleton)
public class Runtime
{
private static Runtime currentRuntime = new Runtime();
private Runtime() { }
public static Runtime getRuntime()
{
return currentRuntime;
}
}
2、系统类:System类
public final class System extends Object
0:类的引入及其描述
系统类System,在java.lang包下,不需要导包。描述说:System类有一些有用的类字段和方法。它并不能实例化。在 System 类提供的方法中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
A:成员变量【Field Summary】
public static PrintStream err
“标准”错误输出流。public static InputStream in
“标准”输入流。public static PrintStream out
“标准”输出流。
B:构造方法【Constructor Summary】
不能实例化,仅仅存在一个私有的构造 private System() { }
C:成员方法【Method Summary】
- a、
public static long currentTimeMillis()
返回当前系统时间,单位是毫秒。结果的精确度取决底层的操作系统,并且可能粒度很大。譬如有的操作系统以十几毫秒为单位测量时间。
/** 获取应用程序的运行时间 */
// 开始程序之前的位置
long start = System.currentTimeMillis();
// 应用程序执行
// 结束程序之后的位置
long end = System.currentTimeMillis();
// 程序实际运行的时间(单位是:毫秒)
long time = end -start;
- b、
public static void gc()
运行垃圾回收器。调用 gc 方法暗示着java虚拟机已经做了一些努力来回收垃圾,以便能够快速地重用这些对象占用地内存。当控制权从方法调用中返回时,虚拟机已经做了最大的努力从所有丢弃的对象中回收了空间。底层实现的原理是:Runtime.getRuntime().gc();
“gc"代表的是"garbage collection”,虚拟机根据当前需要,在独立的线程中自动执行回收过程,甚至不需要显示的调用gc
System.gc()
可用于垃圾回收。当使用System.gc()
来回收某个对象之前,要求程序调用适当的方法来清理资源,在没有明确指定资源清理的情况之下,Java提供了默认的机制来清理该对象的资源,调用继承自根类的Object类的finalize()
方法。
finalize()
方法的作用:释放一个废弃对象所占用的资源,被JVM调用。而子类重写该方法,就可以清理自身对象所占用的资源,该方法没有链式调用,必须手动实现(必须手动调用该方法)
示例:重写父类的finalize实现资源释放
/** 标准的Person类 */
package com.rupeng.system;
public class Person
{
private String name;
private int age;
public Person()
{
super();
}
public Person(String name, int age)
{
super();
this.name = name;
this.age = age;
}
@Override
public String toString()
{
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
protected void finalize() throws Throwable
{
System.out.println("Has been killed : " + this);
super.finalize();
}
}
/** 测试类 */
package com.rupeng.system;
public class Demo
{
public static void main(String[] args)
{
Person p = new Person("Haha", 12);
p.toString();
p = null;
System.gc();
}
}
>>> Has been killed : Person [name=Haha, age=12]
/** 结果表明System.gc()默认调用对象的finalize方法回收废弃对象所占的内存资源 */
从程序的执行结果可以看出,执行
System.gc()
之前,系统会自动调用finalize()
方法清理对象所占的资源,通过super.finalize()
方法可以实现从下往上的finalize()
方法的调用,即先释放自己的资源,再去释放父类的资源
注意:不要在程序执行中频繁调用垃圾回收。因为每一次调用垃圾回收,JVM都会强制启动垃圾回收器运行,这会消耗更多的资源,与正常的Java应用程序争夺资源。建议: 在执行大量的对象的释放时,才调用垃圾回收方法。
finslize()
方法至多执行一次,且对象有且仅有一次的自我拯救的机会,以防止被回收。
- c、
public static void exit(int status)
通过启动虚拟机的关闭序列,终止当前正在运行的Java虚拟机。此方法从不正常返回。可以将变量status作为为一个状态码,根据惯例:status 为 0 表示正常终止;非 0 状态值则是 非正常终止。 底层实现的原理是:Runtime.getRuntime().exit(status);
public static void arraycopy(Object src , // 源数组
int srcPos , // 源数组起始索引
Object dest , // 目标数组
int destPos , // 目标数组起始索引
int length // 复制数组长度
)
3、大数据类:BigInteger类
public class BigIntegerextends Numberimplements Comparable<BigInteger>
(1):类的引入及其描述
java.math包下的类,需要导包。继承自抽象类Numer。描述说:BigInteger 类是不可变的任意精度整数。所有的操作都是以 二进制补码 形式表示BigInteger(如Java的基本整数类型)。BigInteger提供了所有Java基本整数操作符的对应物(如 四则运算),并提供 java.lang.Math 的所有相关方法。另外,BigInteger还提供了以下的运算:模运算、GCD运算、质数测试、素数生成、位操作以及其他的一些操作。
注意:当为任何输入参数传递 null 对象引用时,此类中的所有方法和构造方法都将抛出 NullPointerException。
(2):类的应用
一个推荐使用的构造方法:
public BigInteger(String val)
将字符串解析成BigIntegr对象
四个主要的功能:四则运算:
- a、
+
:public BigInteger add(BigInteger val)
- b、
-
:public BigInteger subtract(BigInteger val)
- c、
*
:public BigInteger multiply(BigInteger val)
- d、
/
:public BigInteger divide(BigInteger val)
- e、返回商和余数 :
public BigInteger[] divideAndRemainder(BigInteger val)
除此之外,BigInteger还提供了很多的整数的操作,取模、素数、质数、位运算等等。
示例:实现大数据的阶乘求和操作
package com.rupeng.biginteger;
import java.math.BigInteger;
public class Demo1
{
public static void main(String[] args)
{
for (int i = 1; i <= 20; i++)
{
System.out.println(jc(new BigInteger("" + i)));
}
System.out.println("-------------------------------");
System.out.println(jcSum(new BigInteger("20")));
}
public static BigInteger jcSum(BigInteger b)
{
BigInteger sum = new BigInteger("0");
for (BigInteger i = new BigInteger("1"); i.subtract(b).toString() != "0"; i = i
.add(new BigInteger("1")))
{
sum = sum.add(jc(i));
}
sum = sum.add(jc(b));
return sum;
}
public static BigInteger jc(BigInteger b)
{
BigInteger p = new BigInteger("1");
for (BigInteger i = new BigInteger("1"); i.subtract(b).toString() != "0"; i = i
.add(new BigInteger("1")))
{
p = p.multiply(i);
}
p = p.multiply(b);
return p;
}
}
4、高精度类:BigDecimal类
首先,先来看一下这样一个例子:
package com.rupeng.bigdecimal;
public class Demo1
{
public static void main(String[] args)
{
double d1 = 0.09 + 0.01;
double d2 = 1.0 - 0.32;
double d3 = 1.015 * 100;
double d4 = 1.301 / 100;
double d5 = 1.0 - 0.12;
System.out.println(d1); // 0.09999999999999999
System.out.println(d2); // 0.6799999999999999
System.out.println(d3); // 101.49999999999999
System.out.println(d4); // 0.013009999999999999
System.out.println(d5); // 0.88
}
}
根据输出的结果,大家可能可能会有太多的疑惑,这实际上只不过是因为 浮点数 在运算时精度不够导致的。再来看一下下面的改写的例子:
package com.rupeng.bigdecimal;
import java.math.BigDecimal;
public class Demo2
{
public static void main(String[] args)
{
BigDecimal bd1 = new BigDecimal(0.09);
BigDecimal bd2 = new BigDecimal(0.01);
BigDecimal bd3 = bd1.add(db2);
System.out.println(bd3); // 0.09999999999999999687749774324174723005853593349456787109375
BigDecimal bd4 = new BigDecimal("0.09");
BigDecimal bd5 = new BigDecimal("0.01");
BigDecimal bd6 = bd4.add(bd5);
System.out.println(bd6); // 0.10
}
}
使用不同构造方法去构造BigDecimal类的对象,在进行计算的时候,第一个的结果 bd3 实际上和上面的例子中的 d1 应该是一样的,d1 因损失精度的原因,损失了一部分的值,而之所以 bd3 也没有得到正确的 0.01 ,则是因为构造BigDecimal对象的时候,是由double类型值作为参数,导致实际上给到BigDecimal的已经不再是 0.09 和 0.01 ,而是比这个值稍小的值。当使用字符串构造BigDecimal对象的时候,则没有值的损失,所以 bd6 的值是准确的 0.10 。 因此,推荐构造BigDecimal使用字符串作为参数的构造方法
。
(1):类的引入及其描述
在运算或存储时,float和double很容易丢失精度吗,这是因为 浮点数 和 整数 的数据存储不一样导致的,大部分时候,都带有有效数字位。为能精确地表示、计算浮点数,Java提供了BigDecimal类。
BigDecimal类 具有不可变性,可以精确表示任意精度的有符号十进制数,可以解决数据丢失的问题(银行的数据处理)
(2):类的应用
一个推荐使用的构造方法:
public BigDecimal(String val)
将字符串解析成BigDecimal对象
四个主要的功能:四则运算:
-
a、
+
:public BigDecimal add(BigDecimal val)
-
b、
-
:public BigDecimal subtract(BigDecimal val)
-
c、
*
:public BigDecimal multiply(BigDecimal val)
-
d、
/
:public BigDecimal divide(BigDecimal val)
-
e、返回商和余数 :
public BigDecimal[] divideAndRemainder(BigDecimal val)
-
f、
public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
返回值:this / divisor ;scale :返回的 BigDecimal 商的标度 ;roundingMode : 要应用的舍入模式 -
g、
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
返回值:this / divisor ;scale :返回的 BigDecimal 商的标度 ;roundingMode : 要应用的舍入模式
public enum RoundingMode extends Enum<RoundingMode>
RoundingMode java.math包下,提供舍入的不同方式。
编号 | 舍入模式 |
---|---|
0 | UP |
1 | DOWN |
2 | CEILING |
3 | FLOOR |
4 | HALF_UP |
5 | HALF_DOWN |
6 | HALF_EVEN |
7 | UNNECESSARY |
所有得舍入模式都是作为枚举类RoundingMode的静态常量值。 |
一个很有用的方法:
- (1)-
public BigDecimal setScale(int newScale)
返回一个 BigDecimal,其标度为指定值,其值在数值上等于此 BigDecimal 的值。如果这不可能,则抛出 ArithmeticException。 (只要是含有小数,永远异常,因所得结果在数值上不等于原来的数
) 仅限于非小数的保留小数位需求- (2)-
public BigDecimal setScale(int newScale, int roundingMode)
- (3)-
public BigDecimal setScale(int newScale, RoundingMode roundingMode)
推荐方式(兼顾了正确性、代码阅读性)
示例:将给定的数字进行四舍五入,并且指定小数位
package com.rupeng.bigdecimal;
import java.math.BigDecimal;
import java.math.RoundingMode;
/** 小数的四则五入,以及保留小数位需求的实现类 */
public class Demo3
{
public static void main(String[] args)
{
BigDecimal bd2 = new BigDecimal("3.1415926");
BigDecimal bd3 = new BigDecimal("3.0");
System.out.println(bd2.setScale(0, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(1, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(2, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(3, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(4, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(5, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(6, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(7, RoundingMode.HALF_UP));
System.out.println(bd2.setScale(8, RoundingMode.HALF_UP));
System.out.println(bd3.setScale(9));
}
}
5、日期类:Date类
public class Date extends Object implements Serializable, Cloneable, Comparable<Date>
0:类的引入及其描述
java.util包下,需要导包。描述说:Date类表示特定的瞬间,精确到毫秒。
A:构造方法【Constructor Summary】
public Date()
以此刻的系统时间毫秒值创建日期对象public Date(long time)
以给定时间毫秒值创建日期对象
Date d1 = new Date(System.currentTimeMillis());
Date d2 = new Date(time);
C:成员方法【Method Summary】
日期和毫秒值的相互转换
public void setTime(long time)
设置时间public long getTime()
获取时间
在JDK1.1之后,绝大多数构造和成员方法都已经过时
,由DateFormat、Calendar及其子类去提供实现。
6、日期格式化类:DateFormat类 、SimpleDateFormat类
public abstract class DateFormatextends Format
public class SimpleDateFormat extends DateFormat
日期格式化类同在java.text包下,需要导包。主要提供了将String和Date相互转换的方法。
A:构造方法
public SimpleDateFormat()
使用默认模式和默认语言环境创建SimpleDateFormat对象。public SimpleDateFormat(String pattern)
用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。public SimpleDateFormat(String pattern, Locale locale)
用给定的模式和给定语言环境的默认日期格式符号构造 SimpleDateFormat。public SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
用给定的模式和日期符号构造 SimpleDateFormat。
注意:如果语言欢迎不支持,请参看DataFormat类中的工厂方法
主要异常:NullPointerException - 如果给定的模式或语言环境为 null ;IllegalArgumentException - 如果给定的模式无效
B:格式化:Date --> String
(1)源自DataFormat父类的成员方法:
public final String format(Date date)
(2)结合自身的构造方法:
public SimpleDateFormat(String pattern)
时间和日起模式
字符 | 含义 |
---|---|
y | 年 |
M | 月 [1-12] |
d | 日 [1-31] |
H | 时 [0-23] |
m | 分 [0-59] |
s | 秒 [0-59] |
S | 毫秒 [0-999] |
F | 月份中的第几星期 |
E | 星期几 |
示例:获取当前日期,并格式化
String pattern = "yyyy年MM月dd日 HH:mm:ss:SSS F M";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String date = sdf.format(new Date());
C:解析:String --> Date
(1)源自DataFormat父类的成员方法:
public Date parse(String source)
解析时可能抛出异常:ParseException
(2)结合自身的构造方法:
public SimpleDateFormat(String pattern)
示例:解析给定格式的时间
String pattern = "yyyy-MM-dd HH:mm:dd";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse("2008-08-08 12:00:00");
案例1:计算出生至今多少天?
package com.rupeng.date_etc;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Demo3
{
public static void main(String[] args) throws ParseException
{
Scanner sc = new Scanner(System.in);
System.out.println("Please enter your date of birth: ");
String birthday = sc.nextLine();
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date start = sdf.parse(birthday);
if (start.getTime() > now.getTime())
{
System.out.println("You are not born ! Are you sure ?");
} else
{
long days = (now.getTime() - start.getTime()) / 1000 / 60 / 60 / 24;
System.out.println("You have benn born " + days + " days.");
}
}
}
案例2:计算某一年的二月有多少天?
package com.rupeng.date_etc;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Demos
{
/** 计算某一年的二月有多少天 */
/** 获取3月1日前一天的天数 "dd" */
public static void main(String[] args) throws ParseException
{
Scanner sc = new Scanner(System.in);
System.out.println("Please enter year: ");
String year = sc.nextLine();
String pattern = "yyyy-MM-dd";
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
Date date = sdf.parse(year + "-03-01");
long time = date.getTime() - 24 * 60 * 60 * 1000;
Date dest = new Date(time);
SimpleDateFormat destSdf = new SimpleDateFormat("dd");
String destStr = destSdf.format(dest);
System.out.println("February has " + destStr + " days in " + year);
sc.close();
}
}
7、日历类:Calendar类、GregorianCalendar类 (公历类)
.public abstract class Calendar extends Object implements Serializable, Cloneable, Comparable<Calendar>
public class GregorianCalendar extends Calendar
0:类的引入及其描述
java.util包下的Calendar是一个抽象类,在具体使用的时候,需要的是它的子类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如:获取下一星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治时间 1970 年 1 月 1 日 00:00:00:0000 ,格里高利历)的偏移量。
与其它语言敏感类一样,Calendar 提供了一个方法 getInstance,已获得此类型的一个通用对象。 Calendar 的 getInstance 方法返回一个Calendar对象,其日历字段已由当前日期和时间初始化:
Calendar rightNow = Calendar.getInstance();
Calendar 对象能够生成为特定语言和日历风格实现日期-时间格式化所需的所有日历字段值。
下面主要来看一下继承自抽象类Calendar的子类 GregorianCalendar 类的成员
。
GregorianCalendar 是 Calendar 的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。
A:成员变量【Field Summary】
日期字段值(YEAR、MONTH、DAY_OF_MONTH、DATE、DAY_OF_MONTH、DAY_OF_WEEK、HOUR、MINUTE、SECOND等) 均为静态成员变量值,且为 int
类型。
MONTH : 从0开始,最大为11。0代表的是January
DAY_OF_WEEK : 一周的第几天。从周日开始计数
继承自Calendar类的GregorianCalendar子类为每个日历字段使用以下默认值(如果该值未定义)
字段 | 默认值 |
---|---|
ERA | AD |
YEAR | 1970 |
MONTH | JANUARY |
DAY_OF_MONTH | 1 |
DAY_OF_WEEK | 一个星期的第一天 |
WEEK_OF_MONTH | 0 |
DAY_OF_WEEK_IN_MONTH | 1 |
AM_PM | AM |
HOUR, HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND | 0 |
默认值不适用于以上未列出的字段。 |
B:构造方法【constructor Summary】
public GregorianCalendar()
在具有默认语言环境的默认时区内使用当前时间构造一个默认的 GregorianCalendar。public GregorianCalendar(int year, int month, int dayOfMonth)
在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar。GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, int second)
为具有默认语言环境的默认时区构造一个具有给定日期和时间设置的 GregorianCalendar。GregorianCalendar(Locale aLocale)
在具有给定语言环境的默认时区内构造一个基于当前时间的 GregorianCalendar。GregorianCalendar(TimeZone zone)
在具有默认语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。GregorianCalendar(TimeZone zone, Locale locale)
在具有给定语言环境的给定时区内构造一个基于当前时间的 GregorianCalendar。
C:成员方法【Method Summary】
- a、获取功能
public int get(int field)
获取具体的日期字段值。譬如 :get(YEAR)
。(继承自父类)public final Date getTime()
返回一个表示此 Calendar 时间值(从历元至现在的毫秒偏移量)的 Date 对象。public long getTimeInMillis()
返回此 Calendar 的时间值,以毫秒为单位。
以及更多的get功能(不常用)
- b、设置功能
public void add(int field, int amount)
根据日历规则,将指定的(有符号的)时间量添加到给定的日历字段中。 有符号是指添加正负数均可。(实现父类的功能)public void set(int field, int value)
设置指定的日期的字段值public final void set(int year, int month, int date)
设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值。保留其他日历字段以前的值。如果不需要这样做,则先调用 clear()。public final void set(int year, int month, int date, int hourOfDay, int minute)
设置日历字段 YEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY 和 MINUTE 的值。保留其他字段以前的值。如果不需要这样做,则先调用 clear()。public final void set(int year, int month, int date, int hourOfDay, int minute,int second)
设置字段 YEAR、MONTH、DAY_OF_MONTH、HOUR、MINUTE 和 SECOND 的值。保留其他字段以前的值。如果不需要这样做,则先调用 clear()。
以及更多的roll功能(不常用),使用add可以更好的实现
-
c、清空功能
public final void clear()
将此 Calendar 的所日历字段值和时间值(从历元至现在的毫秒偏移量)设置成未定义(默认值)public final void clear(int field)
将指定日期字段值设置为未定义(默认值)
-
d、其它不常用的功能
示例1:获取当前时间的年月日时分秒
package com.rupeng.calendar_etc;
import java.util.Calendar;
public class Demo1
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.YEAR) + "-" + c.get(Calendar.MONTH)
+ "-" + c.get(Calendar.DATE) + " " + c.get(Calendar.HOUR) + ":"
+ c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND));
}
}
示例2:获取5年后的10天前
package com.rupeng.calendar_etc;
import java.util.Calendar;
public class Demo2
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
c.add(Calendar.YEAR, 5); // 5年后
c.add(Calendar.DATE, -10); // 10天前
System.out.println(c.get(Calendar.YEAR) + "-"
+ (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DATE));
// 记得月份是从 0 开始
}
}
面试题
如何快速获取任意年份的2月份有多少天?
解答: 三月一日的前一天的天数
-
(1)DateFormat类实现代码参看–上一章节:案例2:计算某一年的二月有多少天?
-
(2)Calendar实现代码
package com.rupeng.calendar_etc;
import java.util.Calendar;
import java.util.Scanner;
/**
* 需求:获取任意年份的二月份的天数
*
* 分析:通常解法是通过判断该年是平年还是闰年?
* 判定的方法是:能否被400整除或不能被100整除但可以被4整除,均为闰年。
* 但是使用日期相关得类处理的话,会更加得简洁。
* 只要使用该年的3月1日创建一个日期相关对象,
* 然后往前推一天即为该年2月份的最后一天,之后获取2月份的天数即可。
*/
public class Demo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
System.out.println("Please enter year: ");
int year = sc.nextInt();
// GregorianCalendar cd = new GregorianCalendar(year, 2, 1);
// cd.add(GregorianCalendar.DAY_OF_MONTH, -1);
// int days = cd.get(GregorianCalendar.DAY_OF_MONTH);
Calendar cd = Calendar.getInstance();
cd.set(year, 2, 1); // 代表:3月1日(因为Month字段是从0开始)
cd.add(Calendar.DATE, -1);
int days = cd.get(Calendar.DATE);
System.out.println("February has " + days + " days in " + year);
sc.close();
}
}
小总结: