黑马程序员-----java入门一DAY14------java的异常处理机制以及类

---------------------- android培训java培训、期待与您交流! ----------------------


异常

异常通俗的理解就是系统出现不正常情况。按照面向对象的思想进行描述,并封装成了对象,

因为问题的产生有产生的原因,有问题的名称,问题的描述等多这个属性存在。

当出现多属性信息最方便的方式就是将这些信息封装。

异常就是java按照面向对象的思想将问题进行对象封装。这样就方便于操作问题以及处理问题。


异常的共性:都有一个异常的名称,并还有问题的描述,问题位置,所以可以不断

抽取形成一个异常的体系


异常体系:Throwable

Error

通常指JVM出现重大问题:运行类不存在或内存溢出等

不需要编写针对性代码对其处理,程序无法处理

Exception

在运行时隐形出现的一些情况,可以通过try,catch,finallly处理


异常处理的两种方式

1 捕获异常:try catch 直接处理可能出现的异常

2 声明异常:throws声明告诉调用者可能的异常,暴露问题,调用者自己处理!


总结:

Exception 和Error的子类类名大都以父类名作为后缀

Java异常其实是对不正常情况的一种描述,并将其封装成对象

Java在设计异常体系时,将容易出现的异常情况都分装成了对象


异常处理格式

异常处理的5个关键字:try,catch finally throw,throws

总结

捕获异常:先补货小异常再捕获大异常

程序是调出来的,而不是写出来的,多测试时程序员的必修课

异常处理后,程序不会因为出现异常而退出


异常处理格式

try{

//可能出现的异常代码

}catch(异常类 对象){

//处理该异常类型的语句

}

[finally]{

//一定会执行的代码

//catch块使用System.exit(1);除外

}

备注 当try语句块出现异常程序会自动跳到catch语句块去找匹配的异常类型,

并执行异常处理语句,finally语句块是异常的统一出口


多异常处理

声明异常时尽可能声明具体异常类型,方便更好的处理

方法声明几个异常就对应有几个catch块

若多个catch块中的异常出现继承关系,父类异常catch块放在最后;

在catch语句块使用Exception类作为异常类型时:

所有子类实例都可以使用类接收(向上转型),即所有的异常对象都可以

使用Exception接收

注意 在java处理多异常时补货小范围的异常必须放在大范围异常之前


java同时捕获多个异常类型

java之前

try{

int a=Integer.parseInt("1");

int b=Integer.parseInt("0");

int c=a/b;

System.out.println(c);

}catch(NumberFormatException e){

e.printStackTrace();

}catch(ArithmeticException e){

e.printStackTrace();

}

java 将多个异常写到同一个catch代码块

java之前

try{

Integer a=Integer.parseInt("1");

Integer b=Integer.parseInt("0");

Integer c=a/b;

System.out.println(c);

}catch(NumberFormatException |ArithmeticException e){

e.printStackTrace();

}


异常的分类

异常分类

编译时被检查异常;——>Checked异常

在程序中必须使用try...catch处理;

编译时不被检测的异常;——>Runtime异常

可以不使用try...catch处理,但一旦出现异常就将由JVM处理


异常的分类之Runtime异常

RuntimeException(运行时异常)是指因设计或实现方式不当而导致的问题.

说白了,就是程序员造成的,程序员小心谨慎是完全可以避免的异常,比如,事先判断

对象是否为null,就可以避免NullPointerException异常,实现检察除数不为零,

就可以避免ArithmeticException异常


特点:

这种异常java编译器不会检察它,也就是说程序中出现这类异常的时候,即便不处理也没有问题

,但是一旦出现异常,程序将异常终止,若采用异常处理,则会被相应的程序执行处理


异常的分类 Checked异常

除了RuntimeException 以及子类,其他的Exception及其子类都是受检查异常,我们也可以

称为非RuntimeException异常

特点:

 java编译器会检查它,也就是说程序一旦出现这类异常,要么是没有

try-catch语句捕获,或throws语句没有声明抛出他,编译就不会通过,也就是

说这种异常,程序要求必须处理


声明异常 throws

在可能出现异常的方法上声明排除可能出现异常的类型

声明的是偶竟可能声明具体的异常,方便更好的处理

当方法不直到处理这种异常,可将该异常交给上一级调用者

来处理RuntimeException类型的异常

方法一旦使用throws声明抛出的方法,自己要么try...catch,要么也

throws;

格式:

public 返回值类型 方法名(参数列表) throws 异常类A,异常类B...{


}


throw

自行抛出一个异常对象,抛出异常类的对象

若throw抛出的是Runtime异常

程序可以显示使用try...catch来捕获并处理,也可以不管,直接交给方法

调用者处理

若throw抛出Checked异常

要么放在try里自己处理 要么放在一个throws声明的方法里面,交给调用者处理


class yichang{
public static void main(String[] args) {
	try {
		fn1(1);
	} catch (Exception e) { e.printStackTrace(); }
		fn2(2);
}
public static void fn1(int a) throws Exception{
	if(a >0) { throw new Exception("fn1 -- a值不合法"); }
}
public static void fn2(int a) {
	if(a >0) { throw new RuntimeException("a值不合法"); }
}
}


throws&throw

throws用于在方法上声明该方法不需要处理的异常类型

throw用于抛出具体异常类的对象

throws与throw的区别

throws用在方法上,后面跟异常类名,可以是多个异常类

throw用在方法内,后面跟异常对象,可以是一个


finally

异常的统一出口

不管try块程序是否异常,也不管哪个catch执行,finally块总会执行

try语句块或会执行的catch语句使用了JVM系统退出语句例外;System.exit(1)

try语必须和catch块或finally同在,不单独存在,二者必须出现一个

不要在finally中使用return或throw语句,否则将会导致try catch中的ruturn

或throw失效


finally块代码只在一种情况下不执行:System.exit(1);




public class yichang {
	public static void main(String[] args) {
		try{
			System.out.println(17/0);
		}catch(Exception e){
			//e.printStackTrace();
			System.out.println("程序错误,请修正!");
		}finally{
			System.out.println("这是finally代码块!");//finally代码块必须执行
		}
	}
}

输出:
程序错误,请修正!
这是finally代码块!


throw和catch同时使用

当异常出现在当前方法中,程序只对异常进行部分处理,还有一些处理需要在方法

的调用者中才能处理完成,此时还应再次抛出异常,这样就可以让方法的调用者也能捕获到异常

	public static void buy(String price) throws Exception {
		try {
			if(price != null)
				Double.parseDouble(price);
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception("价格不能只能是数字组成");
		}
	}
	public static void main(String[] args)  {
		try {
			buy(null);
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

}

常用类

String 表示字符串

String是不可变类,一旦String对象被创建,包含在对象中的字符徐磊是不可变的,直到对象被销毁


StringBuffer 与 StringBuilder

String是不可变类,一旦String对象被创建,包含在对象中的字符序列是不可变的,直到对象被销毁;

 

StringBuffer 与 StringBuilder对象则是可变的!

 

举例说明这两个的好处:(不用每次新建对象,效率高!)


public class Demo22 {
	public static void main(String[] args) {
		
		String s = "";
		long begintime = System.currentTimeMillis();
		for(int i = 1;i <= 10000;i++){
			s += i;
		}
		
		
		long endtime = System.currentTimeMillis();
		long time = endtime - begintime;
		System.out.println("运行时间为:"+time);
		
		StringBuffer s1 = new StringBuffer();
		s = "";
		begintime = System.currentTimeMillis();
		for(int i = 1;i <= 100000;i++){
			s = ""+i;
			s1 = new StringBuffer(s);
		}
		
		endtime = System.currentTimeMillis();
		time = endtime - begintime;
		System.out.println("运行时间为:"+time);
		
	}
}

StringBuffer:  是线程安全的;

StringBuilder:是线程不安全的,性能高点,推荐使StringBuilder;(jdk1.5出现)

StringBuffer的字符序列是可变的(通过append等方法操作)

StringBuffer  和  String之间的转换;

String toString() 返回此序列中数据的字符串表示形式。

StringBuffer(String str):以指定的字符串创建StringBuffer对象。


StringBuffer方法

 

public StringBuilder()构造一个不带任何字符的StringBuilder对象。

StringBuffer(String str) :构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。

StringBuffer append(Object o) :将指定的任意类型对象追加到此StringBuffer 对象。

StringBuffer insert(int offset, Object o) :将任意类型参数的字符串表示形式插入此序列中。

StringBuffer delete(int start, int end) :移除此序列的子字符串中的字符。

StringBuffer deleteCharAt(int index): 移除此序列指定位置的 char。  


/**
 * 用StringBuilder 或StringBuffer:
	把字符串“ABCDE”;
	转变成字符串“A,B,C,D”
 */

public class Demo23 {
	public static void main(String[] args) {
		//第一种方法:往里面插入;
		StringBuilder sb = new StringBuilder("ABCDE");
		sb.deleteCharAt(sb.length()-1);
		System.out.println(sb);
		for (int i = 0; i < sb.length(); i+=2) {
			sb.insert(i, ",");
		}
		sb.deleteCharAt(0);
		
		System.out.println(sb);
		
		
		//第二种方法:往里面追加,要追加必须遍历,必须换为数组!
		sb = new StringBuilder("ABCDE");
		sb.deleteCharAt(sb.length()-1);
		System.out.println(sb);
		char []cs = sb.toString().toCharArray();
		StringBuilder sb1 = new StringBuilder();
		for (char c : cs) {
			sb1.append(c).append(",");
		}
		sb1.deleteCharAt(sb1.length()-1);
		System.out.println(sb1);
	} 
}

Math和Random和UUID

 

Math类

public finalclass Math extends Object

以下X表示double,float,int,long

abs(X x):求绝对值

max(X x1,X x2):求最大值

min(X x1,X x2):求最小值

public staticdouble random():返回带正号的 double值,该值大于等于 0.0 且小于 1.0。和使用new java.util.Random一样

Math.PI;

 

Random类

负责生成伪随机数;

Random() 创建一个新的随机数生成器。

int nextInt() 返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。

int nextInt(intn)  返回一个伪随机数,它是取自此随机数生成器序列的、在 0(包括)和指定值n(不包括)之间均匀分布的 int 值。

package reviewDemo;

public class Demo26 {
	public static void main(String[] args) {
		System.out.println(Math.E);//2.718281828459045
		int a = 12;
		int b = 25;
		
		System.out.println(Math.max(a,b));//这里可以使用静态导入(导入Math类中的方法,这样的话前面就不用写上Math.)
		System.out.println(Math.min(a,b));
	}
}


package reviewDemo;

import java.util.UUID;

public class Demo27 {
	public static void main(String[] args) {
		UUID u = UUID.randomUUID();
		String s = u.toString();
		System.out.println(s);//此时是随机生成的,肯定每次都不一样,全网唯一!
		
		u = new UUID(1222222222, 12);//根据构造方法来
		s = u.toString();
		System.out.println(s);//这一个的UUID是固定的。
	}
}



UUID

UUID(用来标示文件名等(免得文件上传因为名字可能一样而被覆盖),可以保证全网唯一!)

UUID类:用唯一标识符 (UUID) 的类。 UUID 表示一个 128 位的值。

UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。由以下几部分的组合:当前日期和时间(UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同),时钟序列,全局唯一的IEEE机器识别号(如果有网卡,从网卡获得,没有网卡以其他方式获得),UUID的唯一缺陷在于生成的结果串会比较长。

标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx(8-4-4-4-12),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字;

UUID uuid = UUID.randomUUID();

String uid = uuid.toString();



Date和Calendar

 

处理日期,时间;

大部分的方法已过时,不推荐使用,但是你使用过时的方法也不会报错。

Date() 分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒)。

Date(long date)  分配 Date 对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即 1970 年 1 月 1 日 00:00:00 GMT)以来的指定毫秒数。

 

SimpleDateFormat

 

java.text.SimpleDateFormat

SimpleDateFormat 是一个与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。

SimpleDateFormat(String pattern)  用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat。

public final String format(Date date)将一个 Date 格式化为日期/时间字符串。

 public Date parse(String source) throwsParseException:把字符串source表示的时间按source的格式转成Date对象。


Calendar

 

推荐使用处理日期和时间的类Calendar;

是抽象类,不能实例化,通过

static Calendar getInstance() 获得一个Calendar对象。

int get(int field):返回指定日历字段值

静态常量:

YEAR 表示年的字段数字。

MONTH 表示月份字段数字,月份范围是[0,11]。

DATE 表示一个月中的某天。

DAY_OF_MONTH 表示一个月中的某天。

DAY_OF_WEEK 表示一个星期中的某天。

HOUR_OF_DAY / HOUR 表示第几小时

MINUTE 表示第几分钟

SECOND       表示第几秒

 

Date getTime() 返回一个表示此 Calendar 时间值的 Date 对象。

void set(int year, int month, int date, inthour, int minute, int second)   设置字段 YEAR、MONTH、DAY_OF_MONTH、HOUR、MINUTE 和 SECOND 的值。

abstract void add(int field, int amount) 根据日历的规则,为给定的日历字段添加或减去指定的时间量。



System

 

System 类包含一些与系统相关的类字段和方法。它不能被实例化,类中所有属性和方法都是static,可直接被System调用。

 

常用方法:

static void exit(int status) 终止虚拟机的运行.对于发生了异常情况而想终止虚拟机的运行,传递一个非0数值,对于正常情况下退出系统传递0值;

该方法实际调用的是Runtime.getRuntime().exit(intstatus);

static void arraycopy(Object src, intsrcPos, Object dest, int destPos, int length) 数组拷贝

static long currentTimeMillis() 返回以毫秒为单位的当前时间。

String getenv(String name)     获得指定的环境变量;

static void gc()  运行垃圾回收器。

实际上调用了 Runtime中的gc()方法;

Runtime.getRuntime().exec("notepad");

static Properties getProperties()  取得当前的系统属性。

static String getProperty(String key) 取得指定键指示的系统属性。

static String getProperty(String key,String def)  获取用指定键描述的系统属性,def表示默认信息。

 


----------------------- android培训java培训、java学习型技术博客、期待与您交流! ----------------------

你可能感兴趣的:(黑马程序员-----java入门一DAY14------java的异常处理机制以及类)