11、其他对象
11.1System类
11.1.1System类声明
java.lang
类 System
java.lang.System
public final class System
extends Object
System 类包含一些有用的类字段和方法。它不能被实例化。(没有构造函数)
在 System 类提供的设施中,有标准输入、标准输出和错误输出流;对外部定义的属性和环境变量的访问;加载文件和库的方法;还有快速复制数组的一部分的实用方法。
从以下版本开始:
JDK1.0
11.1.2System类字段
static PrintStream | err |
static InputStream | in |
static PrintStream | out |
11.1.3System类方法
方法摘要 | |
static void | arraycopy(Object src, int srcPos,Object dest, int destPos, int length) |
static String | clearProperty(String key) |
static Console | |
static long | currentTimeMillis() |
static void | exit(int status) |
static void | gc() |
getenv() | |
static String | |
static Properties | getProperties()(演示) |
static String | getProperty(String key) |
static String | getProperty(String key,String def) |
static SecurityManager | getSecurityManager() |
static int | identityHashCode(Object x) |
static Channel | inheritedChannel() |
static void | |
static void | loadLibrary(String libname) |
static String | mapLibraryName(String libname) |
static long | nanoTime() |
static void | runFinalization() |
static void | runFinalizersOnExit(boolean value) |
static void | setErr(PrintStream err) |
static void | setIn(InputStream in) |
static void | setOut(PrintStream out) |
static void | setProperties(Properties props) |
static String | setProperty(String key,String value) |
static void | setSecurityManager(SecurityManager s) |
从类 java.lang.Object 继承的方法 |
clone, equals, finalize,getClass,hashCode,notify, notifyAll, toString, wait, wait,wait |
11.1.4System类代码示例
/*
System:类中的方法和属性都是静态的。
out:标准输出,默认是控制台。
in:标准输入,默认是键盘。
描述系统一些信息。
获取系统属性信息:Properties getProperties();
*/
import java.util.*;
class SystemDemo
{
public static void main(String[] args)
{
Properties prop = System.getProperties();
//因为Properties是Hashtable的子类,也就是Map集合的一个子类对象。那么可以通过map的方法取出该集合中的元素。该集合中存储都是字符串。没有泛型定义。
//如何在系统中自定义一些特有信息呢?
System.setProperty("mykey","myvalue");
//获取指定属性信息。
String value = System.getProperty("os.name");
System.out.println("value="+value);
//可不可以在jvm启动时,动态加载一些属性信息呢?
//在java运行时使用 java -Dhaha=qq SystemDemo时可以动态的加载
String v = System.getProperty("haha");
System.out.println("v="+v);
/*
//获取所有属性信息。
for(Object obj : prop.keySet())
{
String value = (String)prop.get(obj);
System.out.println(obj+"::"+value);
}
*/
}
}
11.2Runtime类
11.2.1Runtime类声明:
java.lang
类 Runtime
java.lang.Runtime
public class Runtime
extends Object
每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接。可以通过getRuntime 方法获取当前运行时。
应用程序不能创建自己的 Runtime 类实例。
从以下版本开始:
JDK1.0
另请参见:
11.2.2Runtime类方法
方法摘要 | |
void | addShutdownHook(Thread hook) |
int | availableProcessors() |
exec(String[] cmdarray,String[] envp,File dir) | |
exec(String command,String[] envp,File dir) | |
void | exit(int status) |
long | freeMemory() |
void | gc() |
getLocalizedInputStream(InputStream in) | |
getLocalizedOutputStream(OutputStream out) | |
static Runtime | getRuntime() |
void | halt(int status) |
void | |
void | loadLibrary(String libname) |
long | maxMemory() |
boolean | removeShutdownHook(Thread hook) |
void | runFinalization() |
static void | runFinalizersOnExit(boolean value) |
long | totalMemory() |
void | traceInstructions(boolean on) |
void | traceMethodCalls(boolean on) |
从类 java.lang.Object 继承的方法 |
clone, equals, finalize,getClass,hashCode,notify, notifyAll, toString, wait, wait,wait |
11.2.3Runtime类代码示例:
/*
Runtime对象
该类并没有提供构造函数。
说明不可以new对象。那么会直接想到该类中的方法都是静态的。
发现该类中还有非静态方法。
说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回值类型是本类类型。
由这个特点可以看出该类使用了单例设计模式完成。
该方法是static Runtime getRuntime();
*/
class RuntimeDemo
{
public static void main(String[] args) throws Exception
{
Runtime r = Runtime.getRuntime();
//用记事本打开SystemDemo,java文件
Process p = r.exec("notepad.exe SystemDemo.java");
//Thread.sleep(4000);
//p.destroy();//杀掉由exec创建的进程
}
}
11.3Date类
11.3.1Date类声明
java.util
类 Date
java.util.Date
所有已实现的接口:
Serializable,Cloneable, Comparable<Date>
直接已知子类:
public class Date
extends Object
implements Serializable,Cloneable, Comparable<Date>
类 Date 表示特定的瞬间,精确到毫秒。
在JDK 1.1 之前,类 Date 有两个其他的函数。它允许把日期解释为年、月、日、小时、分钟和秒值。它也允许格式化和解析日期字符串。不过,这些函数的 API 不易于实现国际化。从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和解析日期字符串。Date 中的相应方法已废弃。
尽管 Date 类打算反映协调世界时 (UTC),但无法做到如此准确,这取决于 Java 虚拟机的主机环境。当前几乎所有操作系统都假定 1 天 = 24 × 60 × 60 = 86400 秒。但对于 UTC,大约每一两年出现一次额外的一秒,称为“闰秒”。闰秒始终作为当天的最后一秒增加,并且始终在 12 月 31 日或 6 月 30 日增加。例如,1995 年的最后一分钟是 61 秒,因为增加了闰秒。大多数计算机时钟不是特别的准确,因此不能反映闰秒的差别。
一些计算机标准是按照格林威治标准时 (GMT) 定义的,格林威治标准时和世界时 (UT) 是相等的。GMT 是标准的“民间”名称;UT 是相同标准的“科学”名称。UTC 和 UT 的区别是:UTC 是基于原子时钟的,UT 是基于天体观察的,两者在实际应用中难分轩轾。因为地球的旋转不是均匀的(它以复杂的方式减速和加速),所以 UT 始终不是均匀地流过。闰秒是根据需要引入 UTC 的,以便把 UTC 保持在 UT1 的 0.9 秒之内,UT1 是应用了某些更正的 UT 版本。还有其他的时间和日期系统;例如,基于卫星的全球定位系统 (GPS) 使用的时间刻度与 UTC 同步,但没有 针对闰秒进行调整。有关更多信息的一个有趣来源是美国海军天文台,特别是 Directorate of Time 的网址:
还有它们对 "Systems of Time" 的定义,网址为:
http://tycho.usno.navy.mil/systime.html
在类 Date 所有可以接受或返回年、月、日期、小时、分钟和秒值的方法中,将使用下面的表示形式:
- 年份 y 由整数 y - 1900 表示。
- 月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。
- 日期(一月中的某天)按通常方式由整数 1 至 31 表示。
- 小时由从 0 至 23 的整数表示。因此,从午夜到 1 a.m. 的时间是 0 点,从中午到 1 p.m. 的时间是 12 点。
- 分钟按通常方式由 0 至 59 的整数表示。
- 秒由 0 至 61 的整数表示;值 60 和 61 只对闰秒发生,尽管那样,也只用在实际正确跟踪闰秒的 Java 实现中。于按当前引入闰秒的方式,两个闰秒在同一分钟内发生是极不可能的,但此规范遵循 ISO C 的日期和时间约定。
在所有情形中,针对这些目的赋予方法的参数不需要在指定的范围内;例如,可以把日期指定为 1 月 32 日,并把它解释为 2 月 1 日的相同含义。
从以下版本开始:
JDK1.0
另请参见:
DateFormat, Calendar, TimeZone, 序列化表格
11.3.2Date类构造方法
构造方法摘要 | |
Date() | |
Date(int year, int month, int date) | |
Date(int year, int month, int date, int hrs, int min) | |
Date(int year, int month, int date, int hrs, int min, int sec) | |
Date(long date) | |
Date(String s) |
11.3.3Date类方法
方法摘要 | |
boolean | |
boolean | |
clone() | |
int | |
boolean | |
int | getDate() |
int | getDay() |
int | getHours() |
int | getMinutes() |
int | getMonth() |
int | getSeconds() |
long | getTime() |
int | getTimezoneOffset() |
int | getYear() |
int | hashCode() |
static long | parse(String s) |
void | setDate(int date) |
void | setHours(int hours) |
void | setMinutes(int minutes) |
void | setMonth(int month) |
void | setSeconds(int seconds) |
void | setTime(long time) |
void | setYear(int year) |
toGMTString() | |
toLocaleString() | |
toString() | |
static long | UTC(int year, int month, int date, int hrs, int min, int sec) |
从类 java.lang.Object 继承的方法 |
11.3.4Date类代码示例
import java.util.*;
import java.text.*;
class DateDemo
{
public static void main(String[] args)
{
Date d = new Date();
System.out.println(d);//打印的时间看不懂,希望有些格式。
//将模式封装到SimpleDateformat对象中。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日E hh:mm:ss");
//调用format方法让模式格式化指定Date对象。
String time = sdf.format(d);
System.out.println("time="+time);
long l = System.currentTimeMillis();
Date d1 = new Date(l);
System.out.println("d1:"+d1);
}
}
11.4Calendar类
11.4.1Calendar类声明
java.util
类 Calendar
java.util.Calendar
所有已实现的接口:
Serializable,Cloneable, Comparable<Calendar>
直接已知子类:
public abstract class Calendar
extends Object
implements Serializable,Cloneable, Comparable<Calendar>
Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
该类还为实现包范围外的具体日历系统提供了其他字段和方法。这些字段和方法被定义为protected。
与其他语言环境敏感类一样,Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:
CalendarrightNow = Calendar.getInstance();
Calendar 对象能够生成为特定语言和日历风格实现日期-时间格式化所需的所有日历字段值,例如,日语-格里高里历,日语-传统日历。Calendar 定义了某些日历字段返回值的范围,以及这些值的含义。例如,对于所有日历,日历系统第一个月的值是 MONTH == JANUARY。其他值是由具体子类(例如 ERA)定义的。有关此内容的细节,请参阅每个字段的文档和子类文档。
可以通过调用 set 方法来设置日历字段值。在需要计算时间值(距历元所经过的毫秒)或日历字段值之前,不会解释 Calendar 中的所有字段值设置。调用 get、getTimeInMillis、getTime、add 和 roll 涉及此类计算。
Calendar 有两种解释日历字段的模式,即 lenient 和non-lenient。当 Calendar 处于 lenient 模式时,它可接受比它所生成的日历字段范围更大范围内的值。当 Calendar 重新计算日历字段值,以便由 get() 返回这些值时,所有日历字段都被标准化。例如,lenient 模式下的 GregorianCalendar 将 MONTH == JANUARY、DAY_OF_MONTH == 32 解释为 February 1。
当 Calendar 处于 non-lenient 模式时,如果其日历字段中存在任何不一致性,它都会抛出一个异常。例如,GregorianCalendar 总是在 1 与月份的长度之间生成DAY_OF_MONTH 值。如果已经设置了任何超出范围的字段值,那么在计算时间或日历字段值时,处于 non-lenient 模式下的 GregorianCalendar 会抛出一个异常。
Calendar 使用两个参数定义了特定于语言环境的 7 天制星期:星期的第一天和第一个星期中的最小一天(从 1 到 7)。这些数字取自构造 Calendar 时的语言环境资源数据。还可以通过为其设置值的方法来显式地指定它们。
在设置或获得 WEEK_OF_MONTH 或 WEEK_OF_YEAR 字段时,Calendar 必须确定一个月或一年的第一个星期,以此作为参考点。一个月或一年的第一个星期被确定为开始于getFirstDayOfWeek() 的最早七天,它最少包含那一个月或一年的 getMinimalDaysInFirstWeek() 天数。第一个星期之前的各星期编号为 ...、-1、0;之后的星期编号为 2、3、...。注意,get() 返回的标准化编号方式可能有所不同。例如,特定 Calendar 子类可能将某一年第 1 个星期之前的那个星期指定为前一年的第 n 个星期。
在计算日历字段中的日期和时间时,可能没有足够的信息用于计算(例如只有年和月,但没有日),或者可能有不一致的信息( 例如 "Tuesday, July 15, 1996"(格林威治时间)——实际上,1996 年 7 月 15 日是星期一 )。Calendar 将解析日历字段值,以便用以下方式确定日期和时间。
如果日历字段值中存在任何冲突,则 Calendar 将为最近设置的日历字段提供优先权。以下是日历字段的默认组合。将使用由最近设置的单个字段所确定的最近组合。
YEAR + MONTH +DAY_OF_MONTH
YEAR + MONTH +WEEK_OF_MONTH + DAY_OF_WEEK
YEAR + MONTH +DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
YEAR + DAY_OF_YEAR
YEAR + DAY_OF_WEEK+ WEEK_OF_YEAR
HOUR_OF_DAY
AM_PM + HOUR
如果在选定的字段组合中,还有尚未设置值的任一日历字段,那么Calendar 将使用其默认值。每个字段的默认值可能依据具体的日历系统而有所不同。例如,在GregorianCalendar 中,字段的默认值与历元起始部分的字段值相同:即 YEAR = 1970、MONTH = JANUARY、DAY_OF_MONTH = 1,等等。
注: 对于某些特别时间的解释可能会有某些歧义,可以用下列方式解决:
- 23:59 是一天中的最后一分钟,而 00:00 是下一天的第一分钟。因此,1999 年 12 月 31 日的 23:59 < 2000 年 1 月 1 日的 00:00。
- 尽管从历史上看不够精确,但午夜也属于 "am",,中午属于 "pm",所以在同一天,12:00 am ( 午夜 ) < 12:01 am,12:00 pm ( 中午 ) < 12:01 pm。
日期或时间格式字符串不是日历定义的一部分,因为在运行时,用户必须能够修改或重写它们。可以使用DateFormat 格式化日期。
可以使用三种方法更改日历字段:set()、add() 和 roll()。
set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f 已经被更改。尽管日历字段f 是立即更改的,但是直到下次调用 get()、getTime()、getTimeInMillis()、add() 或 roll() 时才会重新计算日历的时间值(以毫秒为单位)。因此,多次调用 set() 不会触发多次不必要的计算。使用 set() 更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。此外,在重新计算日历字段之后,get(f) 没必要通过调用 set 方法返回 value 集合。具体细节是通过具体的日历类确定的。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 set(Calendar.MONTH, Calendar.SEPTEMBER) 将该日期设置为 1999 年9 月 31 日。如果随后调用 getTime(),那么这是解析 1999 年 10 月 1 日的一个暂时内部表示。但是,在调用 getTime() 之前调用 set(Calendar.DAY_OF_MONTH,30) 会将该日期设置为 1999年 9 月 30 日,因为在调用 set() 之后没有发生重新计算。
add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) + delta),但要带以下两个调整:
Add 规则 1。调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f 中发生的任何溢出为模。溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
Add 规则 2。如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f 发生更改之后,或者在出现其他约束之后,比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。更小的字段表示一个更小的时间单元。HOUR 是一个比 DAY_OF_MONTH 小的字段。对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。
示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。调用 add(Calendar.MONTH, 13) 将日历设置为 2000 年9 月 30 日。Add 规则 1 将 MONTH 字段设置为 September,因为向 August 添加 13 个月得出的就是下一年的 September。因为在 GregorianCalendar 中,DAY_OF_MONTH 不可能是 9 月 31 日,所以 add 规则 2 将DAY_OF_MONTH 设置为 30,即最可能的值。尽管它是一个更小的字段,但不能根据规则 2 调整 DAY_OF_WEEK,因为在 GregorianCalendar 中的月份发生变化时,该值也需要发生变化。
roll(f, delta) 将 delta 添加到 f 字段中,但不更改更大的字段。这等同于调用 add(f, delta),但要带以下调整:
Roll 规则。在完成调用后,更大的字段无变化。更大的字段表示一个更大的时间单元。DAY_OF_MONTH 是一个比 HOUR 大的字段。
示例:请参阅 GregorianCalendar.roll(int, int)。
使用模型。为了帮助理解 add() 和 roll() 的行为,假定有一个用户界面组件,它带有用于月、日、年和底层 GregorianCalendar 的递增或递减按钮。如果从界面上读取的日期为 1999 年 1 月 31 日,并且用户按下月份的递增按钮,那么应该得到什么?如果底层实现使用set(),那么可以将该日期读为 1999 年 3 月 3 日。更好的结果是 1999 年 2月 28 日。此外,如果用户再次按下月份的递增按钮,那么该日期应该读为 1999 年 3 月 31 日,而不是 1999 年 3 月 28 日。通过保存原始日期并使用add() 或 roll(),根据是否会影响更大的字段,用户界面可以像大多数用户所期望的那样运行。
从以下版本开始:
JDK1.1
另请参见:
System.currentTimeMillis(), Date, GregorianCalendar,TimeZone, DateFormat, 序列化表格
11.4.2Calendar类字段
字段摘要 | |
static int | ALL_STYLES |
static int | |
static int | AM_PM |
static int | |
protected boolean | areFieldsSet |
static int | |
static int | DATE |
static int | DAY_OF_MONTH |
static int | DAY_OF_WEEK |
static int | DAY_OF_WEEK_IN_MONTH |
static int | DAY_OF_YEAR |
static int | |
static int | DST_OFFSET |
static int | ERA |
static int | |
static int | FIELD_COUNT |
protected int[] | fields |
static int | FRIDAY |
static int | HOUR |
static int | HOUR_OF_DAY |
protected boolean[] | isSet |
protected boolean | isTimeSet |
static int | |
static int | |
static int | |
static int | LONG |
static int | |
static int | |
static int | MILLISECOND |
static int | MINUTE |
static int | MONDAY |
static int | MONTH |
static int | |
static int | |
static int | |
static int | SATURDAY |
static int | SECOND |
static int | |
static int | SHORT |
static int | SUNDAY |
static int | THURSDAY |
protected long | time |
static int | TUESDAY |
static int | UNDECIMBER |
static int | WEDNESDAY |
static int | WEEK_OF_MONTH |
static int | WEEK_OF_YEAR |
static int | YEAR |
static int | ZONE_OFFSET |
11.4.3Calendar类构造方法
protected | Calendar() |
protected | Calendar(TimeZone zone,Locale aLocale) |
11.4.4Calendar类方法
方法摘要 | |
abstract void | add(int field, int amount) |
boolean | after(Object when) |
boolean | before(Object when) |
void | |
void | clear(int field) |
clone() | |
int | compareTo(Calendar anotherCalendar) |
protected void | complete() |
protected abstract void | computeFields() |
protected abstract void | computeTime() |
boolean | |
int | get(int field) |
int | getActualMaximum(int field) |
int | getActualMinimum(int field) |
static Locale[] | getAvailableLocales() |
getDisplayName(int field, int style,Locale locale) | |
getDisplayNames(int field, int style,Locale locale) | |
int | getFirstDayOfWeek() |
abstract int | getGreatestMinimum(int field) |
static Calendar | getInstance() |
static Calendar | getInstance(Locale aLocale) |
static Calendar | getInstance(TimeZone zone) |
static Calendar | getInstance(TimeZone zone,Locale aLocale) |
abstract int | getLeastMaximum(int field) |
abstract int | getMaximum(int field) |
int | getMinimalDaysInFirstWeek() |
abstract int | getMinimum(int field) |
long | getTimeInMillis() |
getTimeZone() | |
int | hashCode() |
protected int | internalGet(int field) |
boolean | isLenient() |
boolean | isSet(int field) |
abstract void | roll(int field, boolean up) |
void | roll(int field, int amount) |
void | set(int field, int value) |
void | set(int year, int month, int date) |
void | set(int year, int month, int date, int hourOfDay, int minute) |
void | set(int year, int month, int date, int hourOfDay, int minute, int second) |
void | setFirstDayOfWeek(int value) |
void | setLenient(boolean lenient) |
void | setMinimalDaysInFirstWeek(int value) |
void | |
void | setTimeInMillis(long millis) |
void | setTimeZone(TimeZone value) |
toString() |
从类 java.lang.Object 继承的方法 |
11.4.5Calendar类代码示例一
import java.util.*;
import java.text.*;
class CalendarDemo
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
String[] mons = {"一月","二月","三月","四月"
,"五月","六月","七月","八月"
,"九月","十月","十一月","十二月"};
String[] weeks = {
"","星期日","星期一","星期二","星期三","星期四","星期五","星期六",
};
int index = c.get(Calendar.MONTH);
int index1 = c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop((c.get(Calendar.MONTH)+1)+"月");
sop(mons[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
/*
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
String year = sdf.format(d);
System.out.println(year);
*/
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
11.4.6Calendar类代码示例二
import java.util.*;
/*
两个练习:
1,获取任意年的二月有多少天。
思路:根据指定年设置一个时间就是
c.set(year,2,1)//某一年的3月1日。
c.add(Calenar.DAY_OF_MONTH,-1);//3月1日,往前推一天,就是2月最后一天。
2,获取昨天的现在这个时刻。
c.add(Calenar.DAY_OF_MONTH,-1);
class CalendarDemo2
{
public static void main(String[] args)
{
Calendar c = Calendar.getInstance();
//c.set(2012,2,23);
c.add(Calendar.DAY_OF_MONTH,-18);
printCalendar(c);
}
public static void printCalendar(Calendar c)
{
String[] mons = {"一月","二月","三月","四月"
,"五月","六月","七月","八月"
,"九月","十月","十一月","十二月"};
String[] weeks = {
"","星期日","星期一","星期二","星期三","星期四","星期五","星期六",
};
int index = c.get(Calendar.MONTH);
int index1 = c.get(Calendar.DAY_OF_WEEK);
sop(c.get(Calendar.YEAR)+"年");
//sop((c.get(Calendar.MONTH)+1)+"月");
sop(mons[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
11.5Math类
11.5.1Math类声明
java.lang
类 Math
java.lang.Object
java.lang.Math
public final class Math
extends Object
Math
类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
与 StrictMath
类的某些数学方法不同,并非Math
类所有等价函数的实现都定义为返回逐位相同的结果。此类在不需要严格重复的地方可以得到更好的执行。
默认情况下,很多 Math
方法仅调用StrictMath
中的等价方法来完成它们的实现。建议代码生成器使用特定于平台的本机库或者微处理器指令(可用时)来提供Math
方法更高性能的实现。这种更高性能的实现仍然必须遵守Math
的规范。
实现规范的质量涉及到两种属性,即返回结果的准确性和方法的单调性。浮点 Math
方法的准确性根据 ulp(units in the last place,最后一位的进退位)来衡量。对于给定的浮点格式,特定实数值的 ulp 是包括该数值的两个浮点值的差。当作为一个整体而不是针对具体参数讨论方法的准确性时,引入的 ulp 数用于任何参数最差情况下的误差。如果一个方法的误差总是小于 0.5 ulp,那么该方法始终返回最接近准确结果的浮点数;这种方法就是正确舍入。一个正确舍入的方法通常能得到最佳的浮点近似值;然而,对于许多浮点方法,进行正确舍入有些不切实际。相反,对于Math
类,某些方法允许误差在 1 或 2 ulp 的范围内。非正式地,对于 1 ulp 的误差范围,当准确结果是可表示的数值时,应该按照计算结果返回准确结果;否则,返回包括准确结果的两个浮点值中的一个。对于值很大的准确结果,括号的一端可以是无穷大。除了个别参数的准确性之外,维护不同参数的方法之间的正确关系也很重要。因此,大多数误差大于 0.5 ulp 的方法都要求是半单调的:只要数学函数是非递减的,浮点近似值就是非递减的;同样,只要数学函数是非递增的,浮点近似值就是非递增的。并非所有准确性为 1 ulp 的近似值都能自动满足单调性要求。
从以下版本开始:
JDK1.0
11.5.2Math类字段
字段摘要 | |
static double | E |
static double | PI |
11.5.3Math类方法
方法摘要 | |
static double | abs(double a) |
static float | abs(float a) |
static int | abs(int a) |
static long | abs(long a) |
static double | acos(double a) |
static double | asin(double a) |
static double | atan(double a) |
static double | atan2(double y, double x) |
static double | cbrt(double a) |
static double | ceil(double a) |
static double | copySign(double magnitude, double sign) |
static float | copySign(float magnitude, float sign) |
static double | cos(double a) |
static double | cosh(double x) |
static double | exp(double a) |
static double | expm1(double x) |
static double | floor(double a) |
static int | getExponent(double d) |
static int | getExponent(float f) |
static double | hypot(double x, double y) |
static double | IEEEremainder(double f1, double f2) |
static double | log(double a) |
static double | log10(double a) |
static double | log1p(double x) |
static double | max(double a, double b) |
static float | max(float a, float b) |
static int | max(int a, int b) |
static long | max(long a, long b) |
static double | min(double a, double b) |
static float | min(float a, float b) |
static int | min(int a, int b) |
static long | min(long a, long b) |
static double | nextAfter(double start, double direction) |
static float | nextAfter(float start, double direction) |
static double | nextUp(double d) |
static float | nextUp(float f) |
static double | pow(double a, double b) |
static double | random() |
static double | rint(double a) |
static long | round(double a) |
static int | round(float a) |
static double | scalb(double d, int scaleFactor) |
static float | scalb(float f, int scaleFactor) |
static double | signum(double d) |
static float | signum(float f) |
static double | sin(double a) |
static double | sinh(double x) |
static double | sqrt(double a) |
static double | tan(double a) |
static double | tanh(double x) |
static double | toDegrees(double angrad) |
static double | toRadians(double angdeg) |
static double | ulp(double d) |
static float | ulp(float f) |
从类 java.lang.Object 继承的方法 |
clone, equals, finalize,getClass,hashCode,notify, notifyAll, toString, wait, wait,wait |
11.6 Random类
11.6.1Random类声明
java.util
类 Random
java.lang.Object
java.util.Random
所有已实现的接口:
直接已知子类:
public class Random
extends Object
implements Serializable
此类的实例用于生成伪随机数流。此类使用 48 位的种子,使用线性同余公式 (linear congruential form) 对其进行了修改(请参阅Donald Knuth 的The Art of Computer Programming,Volume 3,第 3.2.1 节)。
如果用相同的种子创建两个 Random
实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数字序列。为了保证此属性的实现,为类Random
指定了特定的算法。为了 Java 代码的完全可移植性,Java 实现必须让类Random
使用此处所示的所有算法。但是允许Random
类的子类使用其他算法,只要其符合所有方法的常规协定即可。
Random
类实现的算法使用一个protected
实用工具方法,每次调用它最多可提供 32 个伪随机生成的位。
很多应用程序会发现 Math.random()
方法更易于使用。
从以下版本开始:
JDK1.0
另请参见:
11.6.2Random类构造方法
构造方法摘要 | |
Random() | |
Random(long seed) |
11.6.3Random类方法
方法摘要 | |
protected int | next(int bits) |
boolean | nextBoolean() |
void | nextBytes(byte[] bytes) |
double | nextDouble() |
float | nextFloat() |
double | nextGaussian() |
int | nextInt() |
int | nextInt(int n) |
long | nextLong() |
void | setSeed(long seed) |
从类 java.lang.Object 继承的方法 |
clone, equals, finalize,getClass,hashCode,notify, notifyAll, toString, wait, wait,wait |
11.6.4Random类代码示例
/*
练习。给定一个小数。
保留该小数的后两位。
选作。可以考虑,保留时进行四舍五入。
*/
import java.util.*;
class MathDemo
{
public static void main(String[] args)
{
/*
Random r = new Random();
for(int x=0; x<10; x++)
{
//int d = (int)(Math.random()*10+1);
int d = r.nextInt(10)+1;
sop(d);
}
*/
saveTwo(12.3456,3,true);//12.34
}
public static void saveTwo(double d,int scale,boolean isRound)
{
double base = Math.pow(10,scale);
double num = isRound?Math.round(d*base)/base:((int)(d*base))/base;
sop("num="+num);
/*
double d1 = d*100;
sop("d1="+d1);
d1 = d1+0.5;
double d2 = (int)d1;
sop("d2="+d2);
double d3 = d2/100;
sop("d3="+d3);
*/
}
public static void show()
{
double d = Math.ceil(16.34);//ceil返回大于指定数据的最小整数。
double d1 = Math.floor(12.34);//floor返回小于指定数据的最大整数。
long l = Math.round(12.54);//四舍五入
sop("d="+d);
sop("d1="+d1);
sop("l="+l);
double d2 = Math.pow(2,3);
sop("d2="+d2);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}