JavaSE基础篇


此文章为JavaSE基础篇学习内容


一、介绍

1、Java白皮书

Java“白皮书”的关键术语:简单性、面向对象、分布式、健壮性、安全性、体系结构中立、可移植性、解释型、高性能、多线程、动态性

2、Java版本

Java版本:1.0、1.1、1.2、1.3、1.4、5.0(泛型类、“for each”、自动装箱、枚举、静态导入 )、6、7、8(“函数式”编程)、 9(模板)

3、JDK

JDK:Java Development Kit(Java开发工具包):编写Java程序的程序员使用的软件。
JRE:Java Runtime Environment(Java运行时环境):运行Java程序的用户使用的软件。
在这里插入图片描述
JDK是整个JAVA的核心,包括了Java运行环境JRE(Java Runtime Envirnment)、一堆Java开发工具(javac/java/jdb等)和Java基础的类库(即Java API 包)。
JVM(Java Virtual Machine)就是我们常说的java虚拟机,它是整个java实现跨平台的最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类文件可以在虚拟机上执行。也就是说class并不直接与机器的操作系统相对应,而是经过虚拟机间接与操作系统交互,由虚拟机将程序解释给本地系统执行。
只有JVM还不能成class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。在JDK下面的的jre目录里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。

总而言之,我们利用JDK(调用JAVA API)开发了属于我们自己的JAVA程序后,通过JDK中的编译程序(javac)将我们的文本java文件编译成JAVA字节码,在JRE上运行这些JAVA字节码,JVM解析这些字节码,映射到CPU指令集或OS的系统调用。

二、基础

1、类结构和main函数

一个.java文件只能有一个public class ClassName,且类名和文件名相同。可以有其他的类,但所有的代码都应该放在类内。

psvm的写法固定,只是一个启动函数,寄存在public class内。一个类文件最多只能有一个main函数,没有的就不能主动执行,可以被别人调用执行。

Java文件必须以.java命名。

2、基本类型和运算符

基本类型:boolean、byte、short/int/long、float/double、char

byte存储8位有符号整数,-128 ~ 127

int默认是32位

float是32位,赋值时必须带f

char是一个单一的16位Unicode字符(\u0000 ~ \uffff),char类型可以存储任何字符 char a = 97 -> ‘a’

3、选择和循环结构

if-else

switch-case

int a = 1;
switch(a){
	case 1: System.out.println("1");
			break; //满足后跳出case到default执行
	case 2: System.out.println("2");
			break;
	case 3: System.out.println("3");
			break;
	default: System.out.println("All need");	//不需要break,执行后自动跳出switch		
}
//输出结果是:
1
All need

while / do-while

for,int i int num : nums

break:中断循环并退出

continue:跳出本次循环,继续下次循环

4、自定义函数

自定义函数必须放在类的范围内,通常建议方法是public,直接调用的为static。

重载函数:函数名相同,函数参数的个数或者类型必须有所不同,返回值不同不是重载。

三、对象与类

1、面向对象思想

对象:属性+方法,面向对象像盖浇饭和面向过程像蛋炒饭。

对象是一个变量、类就是类型(规范,是定义),从万千对象中抽取共性。类规定了对象应该有的属性内容和方法,对象是类的具体实现(可以有自己的特性)。

2、面向对象四大特性

面向对象的四大特征:抽象、封装、继承、多态

抽象:将一类对象的共同特征总结出来构造类的过程。包括数据抽象和行为抽象两方面,抽象只关注对象的哪些属性和行为,并不关注这此行为的细节是什么。

封装:一个类想要访问另一个类的属性不能直接访问,需要实例化对象。封装给对象提供了隐藏内部特性和行为的能力,对象提供一些能这被其它对象访问的方法来改变它内部的数据。即把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。

继承:继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。继承的过程,就是从一般到特殊的过程。

多态:多态是同一个行为具有多个不同表现形式或形态的能力。允许相同或不同子类型的对象对同一消息作出不同响应。继承、重写、父类引用指向子类对象。

3、类和对象

创建对象即创建引用指向内存空间(堆)中的对象,对象赋值是引用赋值,而基本类型是直接值拷贝。

new出对象后,内部属性值为默认值(0、false、‘\u0000’、0、0.0f、0.0d)。而函数内的局部变量,编译器不会给默认值,需要初始化后才可使用。类的成员变量会被默认初始化。

对象赋值和基本类型赋值。Java中所有的变量传递都是值传递,当变量是对象时则传递对象的地址,基本类型则传递值。当传递的是对象变量时,因为是指向同一个地址,所以修改其内容时就是在修改原来的值。而传递的是基本类型时,修改的值是副本。

在Java中,任何对象变量的值都是对某个对象的引用,new返回值也是一个引用。 对象变量并没有实际包含一个变量,它只是引用一个变量。

所有的Java对象都存储在堆中。

4、构造函数

构造函数:每个Java类都必须有构造函数,构造函数的名称必须和类名一样,且没有返回值(啥也别写)。没有显示定义,Java编译器自动产生一个空的无形参构造函数。一个类可以有多个构造函数,只要形参列表不相同即可。

每个子类的构造函数的第一句话,都默认调用父类的无参数构造函数super()。除非子类的构造函数第一句话是super,而且super必须放在第一条。

Java具有内存自动回收机制,当变量退出其生命周期后,JVM会自动回收所分配的对象的内存。对象回收效率依赖于垃圾回收器GC。

5、信息隐藏和this

信息隐藏原则:类的成员属性private,提供public的get和set方法修改成员属性的值。

this:this负责指向本类中的成员变量、本类中的成员方法、代替本类的构造函数。

四、继承

1、继承

继承:从多个类别(对象)中提取共性,形成了父类。其他类继承父类,成为子类,也拥有这些共性。子类继承父类所有的属性和方法(但不能直接访问private)。

单根继承原则:每个类都只能继承一个类,如果不写extends都默认继承java.lang.Object类,Object类里面默认就有clone,equals,finalize,getClass,hashCode,toString方法。

每个子类的构造函数的第一句话,都默认调用父类的无参数构造函数super(),除非子类的构造函数第一句话是super,而且super语句必须放在第一条,不会出现连续两次super语句。

2、抽象类和接口

类:属性(0或多个)+方法(0或多个)。一个完整的类:所有的方法都有实现(方法体)。类可以没有方法,但是有方法就肯定要实现,这才是一个完整的类。一个完整的类才可以被实例化。

抽象类:若类中存在方法没有方法体,那所在的类就被定义为抽象类。抽象类关键字abstract声明,抽象方法也加abstract关键字。

子类在调用父类时 无论自己有没有构造方法都会先去执行父类无参的函数。哪怕父类是抽象类。虽然抽象类不能被实例化,但是可以在构造方法中初始化一些参数;也可以在子类中调用父类的构造方法。

public abstract class Shape{
	int area;
	public abstract void calArea();
}

抽象类也是类,更像一个规范/声明。一个类继承于抽象类,就不能继承于其他的(抽象)类。子类可以继承于抽象类,但一定要实现父类全部的抽象方法,否则就也是抽象类。

接口:如果类的所有方法都没有实现,那么这个类就算是接口interface。类只可以继承extends一个类,但是可以实现implements多个接口,继承和实现可以同时。接口设计是为了弥补单根继承的不足。接口里可以定义变量,但是常量,不能有实例字段。

类实现接口,就必须实现所有未实现的方法,否则只能成为一个抽象类。

public interface Sports
{
   public void setHomeTeam();
   public void setVisitingTeam(String name);
}

抽象类和接口:抽象类有构造函数,接口没有构造函数。抽象类可以有main,也能运行,接口没有main函数,抽象类方法可以有private / protected,接口方法都是public,不用写public默认就是。

Arrays类中的sort方法可以对对象数组进行排序,但要求对象所属的类必须实现Comparable接口,即实现compareTo方法,并返回一个int。

3、转型、多态和契约设计

类转型:子类可以转换成父类,而父类不可以转为子类。因为父类有的子类都有,而子类有的父类不一定有。子类转型为父类后,调用普通方法仍然是子类的方法。

Human obj1 = new Man(); //OK, Man extends Human
HumanMan obj2 = new Human(); //illegal, Man is a derived class Human
//父类可以转为子类有一种情况例外,就是这个父类本身就是从子类转化过来的
Man obj3 = (Man)obj1;   //OK, Human obj1 = new Man();即obj1本身就是Man来的。Man o1 = new Man();
Human o2 = (Human)o1;
Man o3 = (Man)o2;
//o1 == o2 : true, o1 == o3 : true 因为比的是引用是指向的内存地址
public class AnimalTest {

	public static void haveLunch(Animal a)	{
		a.eat();
	}
	
	public static void main(String[] args) {
		Animal[] as = new Animal[4];
		as[0] = new Cat();
		as[1] = new Dog();
		as[2] = new Cat();
		as[3] = new Dog();
		
		for(int i=0;i<as.length;i++) {
			as[i].move();  //调用每个元素的自身的move方法
		}
		for(int i=0;i<as.length;i++) {
			haveLunch(as[i]);
		}
		
		haveLunch(new Cat());  //Animal  a = new Cat();  haveLunch(a);
		haveLunch(new Dog());
		haveLunch(
				new Animal()
				{
					public void eat() {
						System.out.println("I can eat from an anonymous class");						
					}
					public void move() {
						System.out.println("I can move from an anonymous class");
					}
				});
	}
}
输出结果:
Cat: I can move
Dog: I can move
Cat: I can move
Dog: I can move
Cat: I can eat
Dog: I can eat
Cat: I can eat
Dog: I can eat
Cat: I can eat
Dog: I can eat
I can eat from an anonymous class

多态:类型转换带来的作用就是多态。子类继承父类的所有方法,但子类可以重新定义一个名字、参数和父类一样的方法即重写(覆盖,不是重载)。

契约设计:类不会直接使用另外一个类,而是采用接口的形式,外部可以空投这个接口下的任意子类对象。

五、static、final和常量设计

1、static

static:变量、方法、类、匿名代码块

static变量:静态变量只依赖于类存在,即通过类名即可方法,不需要实例化对象。类与其他所有的对象实例关于static变量的值都共享在一个共同的空间(栈)。

static方法:静态方法也无需通过对象来引用,而通过类名可以直接引用。静态方法中只能使用静态变量和引用静态方法。


public class Potato {
	static int price = 5;
	String content = "";
	public Potato(int price, String content)
	{
		this.price = price;
		this.content = content;
	}	
	public static void main(String[] a)
	{
		System.out.println(Potato.price); //Potato.content    wrong
		System.out.println("----------------------------------");
		Potato obj1 = new Potato(10,"青椒土豆丝");
		System.out.println(Potato.price);
		System.out.println(obj1.price);
		
		System.out.println("----------------------------------");
		Potato obj2 = new Potato(20,"酸辣土豆丝");
		System.out.println(Potato.price);
		System.out.println(obj2.price);
		
	}
}

输出结果是:
5
--------------------------------
10
10
--------------------------------
20
20

public class StaticMethodTest {
	int a = 111111;
	static int b = 222222;
	public static void hello()
	{
		System.out.println("000000");
		System.out.println(b);
		//System.out.println(a);  //error, cannot call non-static variables
		//hi()                    //error, cannot call non-static method
	}
	public void hi()
	{
		System.out.println("333333");
		hello();                  //ok, call static methods
		System.out.println(a);    //ok, call non-static variables
		System.out.println(b);    //ok, call static variables
	}
	public static void main(String[] a)
	{
		StaticMethodTest.hello();
		//StaticMethodTest.hi(); //error, 不能使用类名来引用非静态方法
		StaticMethodTest foo = new StaticMethodTest();
		foo.hello();  //warning, but it is ok
		foo.hi();     //right
	}
}

在这里插入图片描述


public class StaticBlockTest {

	public static void main(String[] args) {
		System.out.println("0000000000000000000");
		// TODO Auto-generated method stub
		StaticBlock obj1 = new StaticBlock();
		StaticBlock obj2 = new StaticBlock();
	}

}


class StaticBlock
{
	//staticl block > anonymous block > constructor function	
	static
	{
		System.out.println("22222222222222222222");
	}
	{
		System.out.println("11111111111111111111");
	}
	public StaticBlock()
	{
		System.out.println("33333333333333333333");
	}
	{
		System.out.println("44444444444444444444");
	}
}
输出结果是:
00000000000000000000
22222222222222222222
11111111111111111111
44444444444444444444
33333333333333333333
11111111111111111111
44444444444444444444
33333333333333333333

2、单例模式

设计模式:在软件开发过程中,经过验证的,用于解决在特定环境下的、重复出现的、特定问题的解决方案。创建型、结构型和行为型。

单例模式:Singleton,限定某一个类在整个程序运行过程中,只能保留一个实例对象在内存空间。外部不允许new(private 构造函数),内部只允许new一次(static 对象)。

采用static来共享对象实例。采用private构造函数,防止外界new操作。提供public的获得实例方法getInstance()给外部获取统一的内部对象。


public class Singleton {
	private static Singleton obj = new Singleton(); //共享同一个对象
	private String content;
	
	private Singleton()  //确保只能在类内部调用构造函数
	{
		this.content = "abc";
	}
	
	public String getContent() 	{
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}	
	
	public static Singleton getInstance()	{
		//静态方法使用静态变量
		//另外可以使用方法内的临时变量,但是不能引用非静态的成员变量
		return obj;
	}
	
	
	public static void main(String[] args) {
		Singleton obj1 = Singleton.getInstance();
		System.out.println(obj1.getContent());  //abc
		
		Singleton obj2 = Singleton.getInstance();
		System.out.println(obj2.getContent());  //abc
		
		obj2.setContent("def");
		System.out.println(obj1.getContent());
		System.out.println(obj2.getContent());
		
		System.out.println(obj1 == obj2); //true, obj1和obj2指向同一个对象
	}

}

输出结果是:
abc
abc
def
def
true

3、final

final:类、方法、字段

final的变量不能再次赋值,如果是基本类型的变量,不能修改其值。如果是对象实例,那么不能修改其指针(但是可以修改对象内部的值)。

final的类不能被继承,父类中如果有final的方法,子类中不能改写此方法。

4、常量设计

常量设计:常量即不会修改的变量,final:不能修改;static:只要一份。

Java中的常量:public static final UPPER_BOUND = 0; 必须初始化。接口内定义的变量默认是常量。

常量池:Java为很多基本类型的包装类 / 字符串都建立常量池。在常量池中,相同的值只存储一份,节省内存,共享访问。

5、常量池

基本类的包装类:Boolean,Byte,Short,Integer,Long,Character,Float,Double

Float和Double没有缓存(常量池),Java为常量字符串都建立常量池缓存机制。

基本类型的包装类和字符串有两种创建方式:常量式、new对象

//常量式赋值创建,放在栈内存(将被常量化)
Integer a = 10;
String b = "abc";
//new对象进行创建,放在堆内存(不会常量化)
Integer c = new Integer(10);
String d = new String("abc");

Integer


public class BoxClassTest {
	public static void main(String[] args)
	{
		int i1 = 10;
		Integer i2 = 10;                // 自动装箱
		System.out.println(i1 == i2);   //true
		// 自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
		
		Integer i3 = new Integer(10);
		System.out.println(i1 == i3);  //true
		// 自动拆箱  基本类型和包装类进行比较,包装类自动拆箱
		
		System.out.println(i2 == i3); //false
		// 两个对象比较,比较其地址。 
		// i2是常量,放在栈内存常量池中,i3是new出对象,放在堆内存中
		
		Integer i4 = new Integer(5);
		Integer i5 = new Integer(5);
		System.out.println(i1 == (i4+i5));   //true
		System.out.println(i2 == (i4+i5));   //true
		System.out.println(i3 == (i4+i5));   //true
		// i4+i5 操作将会使得i4,i5自动拆箱为基本类型并运算得到10. 
		// 基础类型10和对象比较, 将会使对象自动拆箱,做基本类型比较
		
		Integer i6 = i4 + i5;  // +操作使得i4,i5自动拆箱,得到10,因此i6 == i2.
		System.out.println(i1 == i6);  //true
		System.out.println(i2 == i6);  //true
		System.out.println(i3 == i6);  //false
	}	
}

String

在这里插入图片描述
在这里插入图片描述


public class StringNewTest {
	public static void main(String[] args) {
		String s0 = "abcdef";
		String s1 = "abc";
		String s2 = "abc";
		String s3 = new String("abc");
		String s4 = new String("abc");
		System.out.println(s1 == s2); //true 常量池
		System.out.println(s1 == s3); //false 一个栈内存,一个堆内存
		System.out.println(s3 == s4); //false 两个都是堆内存
		System.out.println("=========================");
		
		String s5 = s1 + "def";    //涉及到变量,故编译器不优化
		String s6 = "abc" + "def"; //都是常量 编译器会自动优化成abcdef
		String s7 = "abc" + new String ("def");//涉及到new对象,编译器不优化
		System.out.println(s5 == s6); //false
		System.out.println(s5 == s7); //false
		System.out.println(s6 == s7); //false
		System.out.println(s0 == s6); //true 
		System.out.println("=========================");

		
		String s8 = s3 + "def";//涉及到new对象,编译器不优化
		String s9 = s4 + "def";//涉及到new对象,编译器不优化
		String s10 = s3 + new String("def");//涉及到new对象,编译器不优化
		System.out.println(s8 == s9); //false
		System.out.println(s8 == s10); //false
		System.out.println(s9 == s10); //false
	}
}

不可变对象:一旦创建,这个对象(状态 / 值)不能被更改了,其内在的成员变量的值就不能修改了。八个基本类型的包装类以及String,BigInteger和BigDecimal等。

//不可变对象是指值对象不再修改,而指针的指向可以修改。
String a = new String("abc");
String b = a;
a = "def";	//此时a又指向了值为"def"的地址中,而b仍然指向"abc"

//不可变对象也是传指针(引用)
public static void change(String b){	//b指向了abc
    b = "def";	//b不指向abc而指向def,而a仍然指向abc,因为String是不可变的,只能新创建。
}
String a = new String("abc");
change(a);	//
System.out.println(a);	//abc

如何创建不可变对象,clone / new一个对象。

所有属性都是final和private的,不提供setter方法,类是final的,或者所有方法都是ifinal,类中包含mutable对象,那么返回拷贝需要深度clone。

不可变对象的优点:只读,线程安全。并发读,提高性能。可以重复使用。缺点:制造垃圾,浪费空间。对不可变对象进行修改时,会新开辟空间,旧对象则被搁置,直到回收。

String:Java字符串是一种典型的不可变对象。由于String不可修改,在拼接字符串或者对字符串做加法时会重新创建一个值,效率很差。使用StringBuffer(同步,线程安全)/ StringBuilder(不同步,线程不安全)类的append方法进行修改。

String a = "abc";			   //常量赋值,栈分配内存
String b = new String("abc");	//new对象,堆分配内存
System.out.println(a.equals(b));//字符串内容比较
System.out.println(a==b);	    //是否指向同一个对象,指针比较

六、package、import和classpath

1、package

package:包名package name尽量唯一,域名是唯一的,因此常用域名逆序做包名。

类的完整名字:包名+类名。com.youth.ClassName 类路径:com\youth\ClassName.java

目录分隔符在Windows上是\,在Linux上是/,在Java中用/均可兼容。

2、import

import:不同包可以通过import类名或包名.*引入类。import必须全部放在package之后,类定义之前。多个import的顺序无关。import尽量精确,不推荐用
*,以免同名引用报错。

3、jar

jar:jar文件实际上是一组class文件的压缩包。Java中所有的类为.java文件格式,.java文件最终会被编译成.class文件(二进制)。

4、命令行执行java文件

命令行执行java文件:java -classpath ,;c:\temp com.youth.ClassName 或者 java -cp “,;c:\test,jar;c:\temp;c:\a bc” com.youth.ClassName

在这里插入图片描述

5、Java访问权限

  1. private:私有的,只能本类访问
  2. default:同一个包内访问
  3. protected:同一个包,子类均可访问
  4. public:公开的,所有类都可以访问

四种都可以用来修饰成员变量、成员方法、构造函数。default和public可以修饰类。

在这里插入图片描述

A.java

package test1;

public class A {
	private int v1 = 1;
	int v2 = 2;
	protected int v3 = 3;
	public int v4 = 4;
	
	private void showV1() 
	{
		System.out.println(v1);
	}
	void showV2()
	{
		System.out.println(v2);
	}
	protected void showV3()
	{
		System.out.println(v3);
	}
	public void showV4()
	{
		System.out.println(v4);
	}
}

B.java:B和A在同一个包下,但没有继承关系,因此B只能通过new方式访问A中private以外的变量和方法

package test1;

//B and A are in the same package
public class B {
	public void show()
	{
		//B is not subclass of A
//		System.out.println(v1);  //error
//		System.out.println(v2);  //error
//		System.out.println(v3);  //error
//		System.out.println(v4);  //error		
//		showV1();   //error
//		showV2();   //error
//		showV3();   //error
//		showV4();   //error
		
		A obj = new A();
		//System.out.println(obj.v1);   error,  private
		System.out.println(obj.v2);
		System.out.println(obj.v3);
		System.out.println(obj.v4);
		
		//obj.showV1();   error,  private
		obj.showV2();
		obj.showV3();
		obj.showV4();
	}
}

C.java:子类C继承父类A,并且C和A在同一个包下,因此可以访问public、default和proteced

package test1;

//C is a subclass of A, and in the same package of A.
public class C extends A {
	public void show()
	{		
		//System.out.println(v1);  error, private
		System.out.println(v2);
		System.out.println(v3);
		System.out.println(v4);		
		//showV1();  error, private
		showV2();
		showV3();
		showV4();
		
		A obj = new A();
		//System.out.println(obj.v1);   error,  private
		System.out.println(obj.v2);
		System.out.println(obj.v3);
		System.out.println(obj.v4);
		
		//obj.showV1();   error,  private
		obj.showV2();
		obj.showV3();
		obj.showV4();
	}
}

D.java:子类D继承父类A,可以以子类方式访问protected和public,不能通过new A()访问proteced

package test2;

import test1.A;

public class D extends A{
	public void show()
	{		
		//System.out.println(v1);  error, private
		//System.out.println(v2);  error, default
		System.out.println(v3);
		System.out.println(v4);		
		//showV1();  error, private
		//showV2();  error, default
		showV3();
		showV4();
		
		A obj = new A();
		//System.out.println(obj.v1);   error,  private
		//System.out.println(obj.v2);   error,  default
		//System.out.println(obj.v3);   error,  protected 只能作为子类才能访问   
		System.out.println(obj.v4);
		
		//obj.showV1();   error,  private
		//obj.showV2();   error,  default
		//obj.showV3();   error   protected 只能作为子类才能访问
		obj.showV4();
	}
}

E.java:与A.java不在同一个包下,也没有继承关系。只能通过new一个A的对象访问public变量和方法

package test2;

import test1.A;

public class E {
	public void show()
	{		
		//E is not a subclass of A. And E is not in the same package of A.
		//System.out.println(v1);  error, private
		//System.out.println(v2);  error, default
		//System.out.println(v3);
		//System.out.println(v4);		
		//showV1();  error, private
		//showV2();  error, default
		//showV3();
		//showV4();
		
		A obj = new A();
		//System.out.println(obj.v1);   error,  private
		//System.out.println(obj.v2);   error,  default
		//System.out.println(obj.v3);   error,  protected 只能作为子类才能访问   
		System.out.println(obj.v4);
		
		//obj.showV1();   error,  private
		//obj.showV2();   error,  default
		//obj.showV3();   error   protected 只能作为子类才能访问
		obj.showV4();
	}
}

七、异常

1、异常分类

异常:程序不正常的行为或者状态。

UncheckedException:编译器不会辅助检查,需要程序员自己管理的异常,以预防为主。包括Error子类(可以不用处理)和RuntimeException子类。

CheckedException:编译器会辅助检查,程序员必须处理,以发生后处理为主。包括非RuntimeException的Exception的子类。

2、异常处理

异常处理:程序返回到安全状态,允许用户保存结果,抓住异常,分析异常内容,并以适当方式关闭程序。

捕获异常:try、catch、finally

try:正常业务逻辑。

catch:try发生异常,将执行catch代码。若无异常,绕之,执行完不会返回try也不会进入下一个catch,而是直接执行finally。因此多种catch时,小(子)异常放前面。

finally:执行try或catch后都必须要执行finally,即使catch内又发生了异常也会执行finally。

try{
  // 程序代码
}catch(异常类型1 异常的变量名1){
  // 程序代码
}catch(异常类型2 异常的变量名2){
  // 程序代码
}finally{
  // 程序代码
}

抛出异常:方法存在可能异常的语句,但不处理,那么可以使用throws来抛出异常。

调用带有throws异常的方法,要么处理这些异常,或者再次向外throws,直到main为止。

一个方法被覆盖,覆盖它的方法必须抛出相同的异常,或者异常的子类。如果父类的方法抛出多个异常,那么重写的子类方法必须抛出异常的子集,也就是不能抛出新(更大)的异常。

3、自定义异常

自定义异常:需要继承Exception类或其子类。

自定义重点在构造函数,调用父类Exception的message构造函数,自定义自己的成员变量,在程序中采用throw主动抛出异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值