第7章 - Java其他对象 和 异常
作者:vwFisher
时间:2019-09-05
GitHub代码:https://github.com/vwFisher/JavaBasicGuide
目录
- 1 其他对象API
- 1.1 System类
- 1.2 Runtime类(单例模式)
- 1.3 Math类
- 1.4 Date类
- 1.5 Calendar类(日历)
- 2 异常
- 2.1 异常概述
- 2.2 异常的分类
- 2.2.1 可控式异常
- 2.2.2 运行时异常
- 2.3 获取异常信息
- 2.4 处理异常
- 2.4.1 使用 try...catch 处理异常
- 2.4.2 使用 try...catch...finally 处理异常
- 2.4.3 使用 try...finally 处理异常
- 2.4.4 抛出异常
- 2.4.4.1 使用throws声明抛出异常
- 2.4.4.2 使用throw语句抛出异常
- 2.5 自定义异常
- 2.5.1 创建自定义异常类
- 2.5.2 使用自定义异常类
- 2.5.3 异常的使用原则
1 其他对象API
1.1 System类
(basic.sysobj.SystemDemo)
属性 | 说明 |
---|---|
final InputStream in | 标准 输入流 |
final PrintStream out | 标准 输出流 |
final PrintStream err | 标准 错误输出流 |
静态方法 | |
void setIn(InputStream in) | 重新分配 标准 输入流 |
void setOut(PrintStream out) | 重新分配 标准 输出流 |
void setErr(PrintStream err) | 重新分配 标准 错误输出流 |
Console console() | 返回与当前 Java虚拟机 关联的唯一 Console 对象(如果有) |
Channel inheritedChannel() | 返回从创建此 Java虚拟机 的实体中继承的信道 |
void setSecurityManager(final SecurityManager s) | 设置系统安全性 |
SecurityManager getSecurityManager() | 获取系统安全接口 |
native long currentTimeMillis() | 返回以毫秒为单位的当前时间 |
native long nanoTime() | 返回最准确的可用系统计时器的当前值, 以毫微秒为单位 |
native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) | 从指定源数组中赋值一个数组, 从指定的位置开始复制, 到目标数组的指定位置结束,目标数组多的将设置默认值, 少的则报异常, 长度不够 src: 源数组 srcPos: 开始复制的位置 dest: 目标数组 destPos: 目标数组开始复制的位置 length: 复制的长度 |
native int identityHashCode(Object x) | 返回给定对象的哈希码, 该代码与默认的方法 hashCode() 返回的代码一样, 无论给定对象的类是否重写 hashCode() |
Properties getProperties() | 确定当前的系统属性 |
String lineSeparator() | UNIX/LINUX 返回 \n Windows 返回 \r\n |
void setProperties(Properties props) | 将系统属性设置为Properties参数 |
String getProperty(String key) | 获取指定键指示的系统属性 |
String getProperty(String key, String def) | 获取用指定键描述的系统属性 |
String setProperty(String key, String value) | 设置指定键指示的系统属性 |
String clearProperty(String key) | 移除指定key的系统属性 |
String getenv(String name) | 获取指定的环境变量值 |
java.util.Map |
返回一个不能修改的当前系统环境的字符串映射视图 |
void exit(int status) | 终止当前正在运行的Java虚拟机 |
void gc() | 运行垃圾回收器 |
void runFinalization() | 运行处于挂起终止状态的所有对象的终止方法 |
void runFinalizersOnExit(boolean value) | 已过期, 该方法具有固有的不安全性. 它可能对正在使用的对象调用终结方法, 而其他线程同时正在操作这些对象, 从而导致不正确的行为或死锁 |
void load(String filename) | 从作为动态库的本地文件系统中以指定的文件名加载代码文件 |
void loadLibrary(String libname) | 加载由libname参数指定的系统库 |
native String mapLibraryName(String libname) | 将一个库名称映射到特定于平台的、表示本机库的字符串中 |
1.2 Runtime类(单例模式)
(basic.sysobj.RuntimeDemo)
属性和方法 | 说明 |
---|---|
static Runtime getRuntime() | 返回与当前 Java 应用程序相关的运行时对象(单例模式) |
void exit(int status) | 通过启动虚拟机的关闭序列, 终止当前正在运行的Java虚拟机 |
给JVM添加关闭钩子,当JVM关闭的时候,会执行系统中已经设置的所有通过方法addShutdownHook添加的钩子,执行完这些钩子后,JVM才会关闭(可以进行内存清理、对象销毁等操作) | |
void addShutdownHook(Thread hook) | 注册新的虚拟机来关闭钩子 |
boolean removeShutdownHook(Thread hook) | 取消注册某个先前已注册的虚拟机关闭钩子 |
void halt(int status) | 强行终止目前正在运行的 Java 虚拟机 |
[已过时] 此方法本身具有不安全性. 它可能对正在使用的对象调用终结方法, 而其他线程正在操作这些对象, 从而导致不正确的行为或死锁 | |
Process exec(String command) | 在单独的进程中执行指定的字符串命令 eg:如打开系统的文本,execute xxx.exe |
Process exec(String command, String[] envp) | 在指定环境的单独进程中执行指定的字符串命令 |
Process exec(String command, String[] envp, File dir) | 在有指定环境和工作目录的独立进程中执行指定的字符串命令 |
Process exec(String cmdarray[]) | 在单独的进程中执行指定命令和变量 |
Process exec(String[] cmdarray, String[] envp) | 在指定环境的独立进程中执行指定命令和变量 |
Process exec(String[] cmdarray, String[] envp, File dir) | 在指定环境和工作目录的独立进程中执行指定的命令和变量 |
native int availableProcessors() | 向Java虚拟机返回可用处理器的数目 |
native long freeMemory() | 返回Java虚拟机中的空闲内存量 |
native long totalMemory() | 返回Java虚拟机中的内存总量 |
native long maxMemory() | 返回Java虚拟机试图使用的最大内存量 |
native void gc() | 运行垃圾回收器 |
static native void runFinalization0() | |
void runFinalization() | 运行挂起finalization的所有对象的终止方法 |
native void traceInstructions(boolean on) | 启用/禁用指令跟踪 |
native void traceMethodCalls(boolean on) | 启用/禁用方法调用跟踪 |
void load(String filename) | 加载作为动态库的指定文件名 |
void loadLibrary(String libname) | 加载具有指定库名的动态库 |
InputStream getLocalizedInputStream(InputStream in) | 已过时, 从JDK1.1 开始, 将本地编码字节流转换为Unicode字符流的首选方法是使用InputStreamReader和BufferedReader类 |
OutputStream getLocalizedOutputStream(OutputStream out) | 已过时, 从JDK1.1开始, 将Unicode字符流转换为本地编码字节流的首选方法是使用OutputStreamWriter、BufferedWriter和PrintWriter类 |
1.3 Math类
(basic.sysobj.MathDemo)
属性和方法(静态) | 说明 |
---|---|
final double E = 2.7182818284590452354 | 比任何其他值都更接近e(即自然对数的底数)的double值 |
final double PI = 3.14159265358979323846 | 比任何其他值都更接近pi(即圆的周长与直径之比)的double值 |
double sin(double a) | 返回角的三角正弦 |
double cos(double a) | 返回角的三角余弦 |
double tan(double a) | 返回角的三角正切 |
double sinh(double x) | 返回 double 值的双曲线正弦 |
double cosh(double x) | 返回 double 值的双曲线余弦 |
double tanh(double x) | 返回 double 值的双曲线余弦 |
double asin(double a) | 返回一个值的反正弦; 返回的角度范围在 -pi/2 到 pi/2 之间 |
double acos(double a) | 返回一个值的反余弦; 返回的角度范围在 0.0 到 pi 之间 |
double atan(double a) | 返回一个值的反正切; 返回的角度范围在 -pi/2 到 pi/2 之间 |
double atan2(double y, double x) | 将矩形坐标(x, y)转换成极坐标(r, theta), 返回所得角theta |
double toRadians(double angdeg) | 将用角度表示的角转换为近似相等的用弧度表示的角 |
double toDegrees(double angrad) | 将用弧度表示的角转换为近似相等的用角度表示的角 |
double exp(double a) | 返回欧拉数 e 的 double 次幂的值 |
double expm1(double x) | 返回 ex -1 |
double log(double a) | 返回 double 值的自然对数(底数是 e) |
double log10(double a) | 返回 double 值的底数为 10 的对数 |
double log1p(double x) | 返回参数与 1 之和的自然对数 |
double sqrt(double a) | 返回正确舍入的 double 值的正平方根 |
double cbrt(double a) | 返回 double 值的立方根 |
double IEEEremainder(double f1, double f2) | 按照 IEEE 754 标准的规定, 对两个参数进行余数运算 |
double ceil(double a) | (天花板)返回最小的(最接近负无穷大)double值, 该值大于等于参数, 并等于某个整数 |
double floor(double a) | (地板)返回最大的(最接近正无穷大)double值, 该值小于等于参数, 并等于某个整数 |
int/long round(float/double a) | (等同于floor(a+5))返回最接近参数的 int/long |
double pow(double a, double b) | 返回第一个参数的第二个参数次幂的值 |
double rint(double a) | 返回最接近参数并等于某一整数的 double 值 |
double random() | 返回带正号的 double 值,该值大于等于 0.0 且小于 1.0 |
int addExact(int x, int y) | |
long addExact(long x, long y) | |
int subtractExact(int x, int y) | |
long subtractExact(long x, long y) | |
int multiplyExact(int x, int y) | |
long multiplyExact(long x, long y) | |
int incrementExact(int a) | |
long incrementExact(long a) | |
int decrementExact(int a) | |
long decrementExact(long a) | |
int negateExact(int a) | |
long negateExact(long a) | |
int toIntExact(long value) | |
int floorDiv(int x, int y) | |
long floorDiv(long x, long y) | |
int floorMod(int x, int y) | |
long floorMod(long x, long y) | |
int/long/float/double | |
abs(int/long/float/double a) | 返回对应int/long/float/double值得绝对值 |
int/long/float/double max(int/long/float/double a, int/long/float/double b) | 返回两个 int/long/float/double值中较大的一个 |
int/long/float/double min(int/long/float/double a, int/long/float/double b) | 返回两个 int/long/float/double值中较小的一个 |
float/double ulp(float/double d) | 返回参数的 ulp 大小 |
float/double signum(float/double d) | 返回参数的符号函数;如果参数为 0,则返回 0;如果参数大于 0,则返回 1.0;如果参数小于 0,则返回 -1.0 |
double hypot(double x, double y) | 返回 sqrt(x2 +y2),没有中间溢出或下溢 |
float/double copySign(float/double magnitude, float/double sign) | 返回带有第二个浮点参数符号的第一个浮点参数 |
int getExponent(float/double d) | 返回 float/double 表示形式中使用的无偏指数 |
float/double nextAfter(float/double start, float/double direction) | 返回第一个参数和第二个参数之间与第一个参数相邻的浮点数 |
float/double nextUp(float/double d) | 返回 d 和正无穷大之间与 d 相邻的浮点值 |
float/double nextDown(float/double d) | |
float/double scalb(float/double d, int scaleFactor) | 返回 d × 2scaleFactor,其舍入方式如同将一个正确舍入的浮点值乘以 float/double 值集合中的一个值 |
double powerOfTwoD(int n) | |
float powerOfTwoF(int n) |
1.4 Date类
(basic.sysobj.DateDemo)
日期对象和毫秒值之间的转换
一、毫秒值 ==> 日期对象
- 通过Date对象的构造方法 new Date(timeMillis);
- 还可以通过setTime设置
二、日期对象 ==> 时间戳(13位毫秒值)
- Date对象提供getTime()
三、日期对象 ==> 日期格式字符串
Date date = new Date();
// 获取日期格式对象。具体着默认的风格。 FULL LONG等可以指定风格。
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
// System.out.println(dateFormat);
// 如果风格是自定义的如何解决呢?
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
String str_date = dateFormat.format(date);
System.out.println(str_date);
四、日期格式字符串 ==> 日期对象
使用的是DateFormat类中的parse()方法.
String str_date = "2012年4月19日";
str_date = "2011-8-17";
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.LONG);
dateFormat = new SimpleDateFormat("yyy-MM-dd");
Date date = dateFormat.parse(str_date);
System.out.println(date);
1.5 Calendar类(日历)
(basic.sysobj.CalendarDemo)
Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;
int day = c.get(Calendar.DAY_OF_MONTH);
int week = c.get(Calendar.DAY_OF_WEEK);
System.out.println(year + "年" + month + "月" + day + "日" + getWeek(week));
2 异常
(basic.exceptions.exceptionDemo)
2.1 异常概述
异常:是在运行时期发生的不正常情况。Java把程序中可能会发生的错误称为异常,并提供Throwable的超类
Throwable
|-- Error及其子类:指示合理的应用程序不应该试图捕获的严重问题
1).通常出现重大问题如:运行类不存在或者内存溢出等(是由JVM抛出的严重性的问题)
2).这种问题发生一般不编写针对代码对其处理
|-- Exception及其子类:给出合理的应用程序需要捕获的异常
在运行时运行出行出现的情况,可以通过 try catch finally 结合 thorws、throw
可抛性:throws throw,凡是可以被这两个关键字所操作的类和对象都具备可抛性
对于 Exception 可以 catch(Exception e),对于 Error 必须使用 catch(Throwable e) 才能捕获,但对于 Error错误,不建议抛异常处理,Java系统级别的Error,系统解决完毕就可以了
2.2 异常的分类
异常的分类:
1.编译时被检测异常
只要是 Exception 和其子类都是, 除了特殊子类 RuntimeException 体系。
这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。这样的问题可以针对性处理,
2.编译时不检测异常(运行时异常,RuntimeException)
就是 Exception 中的 RuntimeException 和其子类。
这种问题的发生,无法让功能继续,运算无法进行,更多是因为调用者的原因导致的而或者引发了内部状态的改变导致的。那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行修正。
所以自定义异常时,要么继承Exception。要么继承RuntimeException。
在 Java 中可以捕获的异常(即 Exception 类的子类),分为可控式异常和运行时异常两种类型
2.2.1 可控式异常
在Java中把那些可以预知的错误(从文件中读取数据,对数据库进行操作,在程序编译时对程序可能存在的错误进行处理,并给出具体的错误信息),我们把这些错误称为可控式异常。常见的可控式异常及说明
异常 | 说明 |
---|---|
IOException | 当发送某种I/O异常, 抛出该异常 |
SQLException | 提供关于数据库访问错误或其他错误信息的异常 |
ClassNotFoundException | 类没有找到异常 |
NoSuchFieldException | 类不包含指定名称的字段时抛出该异常 |
NoSuchMethodException | 无法找到某一特定方法时, 抛出该异常 |
由于在构造方法中加载 basic 包中的 Test 类时,Java 虚拟机没有找到 Test 类,从而引发了ClassNotFoundException 异常,所以在控制台输出了 ClassNotFoundException 这样的异常信息
2.2.2 运行时异常
在 Java 中有些错误是不能被编译器检测到的。例如:
- 进行0作为除数抛出的异常
- 试图把一个不是由数字组成的字符串使用 Integer 类的 parseInt() 方法转换为整数等。
Java的编译器是检测不到的,因而能够正常编译,但是在运行时就会发生异常,把这种异常称之为运行时异常,常见的运行时异常及说明
异常 | 说明 |
---|---|
IndexOutOfBoundsException | 指示某集合或数组的索引值超出范围是抛出该异常 |
NullPointerException | 用程序试图在需要对象的地方使用 null 时,抛出该异常 |
ArithmeticException | 当出现异常的运算条件时,抛出该异常 |
IllegalArgumentException | 抛出的异常表明向方法传递了一个不合法或不正确的参数 |
ClassCaseException | 当试图将对象强制转换为不是实例的子类时,抛出该异常 |
2.3 获取异常信息
在 Java 中 java.lang.Throwable 类是所有异常类的超类,该类提供了获得异常信息的方法
方法 | 说明 |
---|---|
String getLocalizedMessage() | 获得此Throwable的本地化描述 |
String getMessage() | 获得此Throwable的详细消息字符串 |
void printStackTrace() | 将此Throwable及其栈踪迹输出至标准错误流 |
String toString() | 获取此Throwable的简短描述 |
2.4 处理异常
异常处理的原则:
- 函数内容如果抛出需要检测的异常,那么函数上必须要声明 throws。否则必须在函数内用 try catch 捕捉,否则编译失败.
- 如果调用到了声明异常的函数,要么 try catch 要么 throws,否则编译失败。
- 什么时候catch,什么时候 throws 呢?功能内容可以解决,用catch。解决不了,用throws告诉调用者,由调用者解决
- 一个功能如果抛出了多个异常,那么调用时,必须有对应多个 catch 进行针对性的处理。内有几个需要检测的异常,就抛几个异常,抛出几个,就 catch 几个。
异常的注意事项
- 子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类方法只能抛出父类的异常或该异常的子类。
- 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
简单说:子类覆盖父类只能抛出父类的异常或者子类或者子集。
注意:如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try
在 Java 语言中当程序发生异常时,可以使用 try、catch 和 finally 异常处理的关键字
格式:
try...catch
try...catch...finally
try...finally
在以下4种特殊情况下,finally块不会被执行
- 在 finally 语句块第一行发生了异常。因为在其他行,finally块还是会得到执行
- 在前面的代码中用了 System.exit(int) 已退出程序。 exit是带参函数;若该语句在异常语句之后,finally会执行
- 程序所在的线程死亡。
- 关闭CPU。
2.4.1 使用 try...catch 处理异常
对于程序中可能发生异常的,可以将其添加到 try...catch 语句块中,这样当程序发生异常时,就可以对其进行相应处理
try {
需要正常执行的语句;
} catch (Exception e) {
对异常进行处理的语句;
}
- try 和 catch 之间的 {} 的内容:是程序需要正常执行但又可能发生异常的语句
- catch 后的 () 的内容:程序需要处理的异常类型
- catch 后的 {} 的内容:对发生该异常类型的相应处理的语句
2.4.2 使用 try...catch...finally 处理异常
try {
需要正常执行的语句;
} catch (Exception e) {
对异常进行处理的语句;
} finally {
一定会执行的语句;
}
- finally 后的 {} 的内容,不管程序是否发生异常都会执行的语句(通常用于 try...catch 执行完后进行垃圾回收,释放资源,关闭数据库连接,关闭IO流等操作)
2.4.3 使用 try...finally 处理异常
try {
需要正常执行的语句;
} finally {
一定会执行的语句;
}
2.4.4 抛出异常
throws 和 throw 的区别
throws | throw |
---|---|
thorws 使用在函数上 | throw 使用在函数内 |
throws 抛出的是异常类,可以抛出多个,用逗号隔开 | throw抛出的是异常对象 |
2.4.4.1 使用throws声明抛出异常
throws通常用于方法声明,方法中可能存在异常,却不想在方法中对异常进行处理,就可以在声明方法时使用 throws 声明抛出的异常(让调用者来处理该异常)。若需要 throws 声明抛出多个异常,各异常之间用逗号分隔
数据类型 方法名(形参列表) throws 异常类1, 异常类2... {
方法体
}
- 数据类型: 基本数据类型或对象类型
- 方法名: Java语言的合法标识符
- throws: 抛出异常的关键字
- 异常类: Java语言的异常类或自定义异常类
- 方法体: 该方法需要执行的语句
2.4.4.2 使用throw语句抛出异常
在通常情况下,程序发生错误时系统会自动抛出异常,而有时希望程序自行抛出异常,可以使用throw语句来实现。throw语句通常用在方法中,在程序中自行抛出异常
throw new Exception("对异常的说明")
- throw: 抛出异常的关键字
- Exception: 异常类(可以是自定义的异常类)
2.5 自定义异常
自定义异常:对于角标是整数不存在,可以用角标越界表示,对于负数为角标的情况,准备用负数角标异常来表示。
但Java没有定义负数角标这种异常. 那么可以将负数角标进行自定义描述. 并封装成对象.
【注: 如果让一个类称为异常类, 必须要继承异常体系, 因为只有称为异常体系的子类才有资格具备可抛性. 才可以被两个关键字所操作, throws throw】
2.5.1 创建自定义异常类
创建自定义的异常类需要继承自Exception类, 并提供含有一个String类型形参的构造方法, 该形参就是异常的描述信息, 可以通过getMessage()方法获得, 例如:
public class NewException extends Exception {
public NewException(String s) {
super(s);
}
}
自定义异常类NewException, 也就是说NewException是自定义异常类的名称, 该类继承自Exception类, 该类构造方法的形参s是需要传递的异常描述信息, 该信息可以通过异常类的getMessage()方法获得
2.5.2 使用自定义异常类
使用自定义异常类可以通过throw语句抛出异常
try {
...
} catch (NetException e) {
throw new NetException("异常描述");
}
2.5.3 异常的使用原则
使用异常可以捕获程序中的异常,但是异常的使用也要遵循一定的规则,下面是异常类的几项使用原则:
- 不要过多地使用异常,这样会增加系统的负担
- 在方法中使用 try...catch 语句块捕获异常时,要对异常作出处理
- try...catch 语句块的范围不要太大,这样不利于对异常的分析
- 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或子异常