6.内部类、异常处理

内部类、异常处理

6.1什么是内部类?内部类有几种?每一中内部类如何表示有那些特征?
内部类
将一个类定义在另一个类里面,形成了包含关系。
内部类–被包含的类
外部类–包含内部类的类。

1.成员内部类
格式:
public class 外部类{

public class 成员内部类{

}
}
1.成员内部类中的变量和方法的调用关系。
1.成员内部类的构造方法中可以访问成员内部类实例变量/成员内部类的实例方法,默认this.,可以省略this.
2.成员内部类的构造方法中可以访问成员内部类中其他的构造方法,通过new访问
3.成员内部类的实例方法中中可以访问成员内部类实例变量/成员内部类的实例方法,默认this.,可以省略this.
4.成员内部类的实例方法中中可以访问成员内部类构造方法,通过new访问

2.成员内部类中的方法访问外部类中的变量和方法
1.成员内部类的构造方法中可以访问外部类的实例变量/外部类的实例方法,默认外部类的类名.this,可以省略外部类的类名.this。
2. 成员内部类的构造方法中可以访问外部类的类变量/类方法,默认类名访问,也可以外部类的类名.this,可以省略类名/外部类的类名.this。
3.成员内部类的构造方法中可以访问外部类的构造方法,通过new访问。
4.成员内部类的实例方法中可以访问外部类的实例变量/外部类的实例方法,默认外部类的类名.this,可以省略外部类的类名.this。
5. 成员内部类的实例方法中可以访问外部类的类变量/类方法,默认类名访问,也可以外部类的类名.this,可以省略类名/外部类的类名.this。
6.成员内部类的实例方法中可以访问外部类的构造方法,通过new访问。
3.外部类中的方法访问成员内部类中的变量和方法
1外部类的构造方法/实例方法中可以访问成员内部类的构造方法【new】,实例变量/实例方法【对象调用】
2.外部类的类方法中不能访问成员内部类。
4.其他类中访问成员内部类中的变量和方法
其他中可以访问成员内部类,先创建外部类对象,然后在创建内部类对象

package com.click369.test1;
//外部类
public class TestClass3 {
	//InnerClass--成员内部类
	public class InnerClass{
		//成员内部类的实例变量
		public  int  innerid=1001;
		//成员内部类的构造方法
		public  InnerClass(){
		}
		//成员内部类的实例方法
		public void  test1(){
		}
	}
}
package com.click369.test1;
public class OtherClass {
	public OtherClass(){
		//TestClass3.InnerClass  inner=new TestClass3().new InnerClass();
		TestClass3 t3=new TestClass3();
		TestClass3.InnerClass  inner=t3.new InnerClass();
		System.out.println(inner.innerid);
		inner.test1();
	}
	public void testOther(){
		TestClass3.InnerClass  inner=new TestClass3().new InnerClass();
		//TestClass3 t3=new TestClass3();
		//TestClass3.InnerClass  inner=t3.new InnerClass();
		System.out.println(inner.innerid);
		inner.test1();
	}
	public static  void testStaticOther(){
		TestClass3.InnerClass  inner=new TestClass3().new InnerClass();
		//TestClass3 t3=new TestClass3();
		//TestClass3.InnerClass  inner=t3.new InnerClass();
		System.out.println(inner.innerid);
		inner.test1();
	}
}

2.方法内部类—在这里我们可以认为方法内部类就相当于方法中的一个局部变量。
将java类定义在某一个方法中。
1、定义方法内部类的时候没有访问修饰符
2.方法内部类中不能出现类变量和类方法
3.方法内部类中的构造方法/实例方法,可以访问本方法中的局部变量,jdk8.0之前需要使用final修饰局部变量,包括参数
4方法内部类中的构造方法/实例方法,可以访问外部类的实例变量/实例方法,默认外部类类名.this. , 可以省略外部类类名.this.
5.方法内部类中的构造方法/实例方法,可以访问外部类的类变量/类方法,默认外部类类名,也可以外部类类名.this. ,可以省略外部类类名/外部类类名.this.
6.定义该方法内部类的方法中可以访问这个方法内部类中的变量和方法,对象访问
7.外部类中的方法中是不能访问方法内部类的。【方法内部类当于方法中的一个局部变量】

package com.click369.test2;

import com.click369.test1.TestClass2.InnerClass;

public class TestClass {
		//外部类的实例变量
		public  int testid=1000;
		//外部类的类变量
		public  static  String testname="lisi";
		//外部类的构造方法
		public TestClass(){
			
		}
		//外部类的实例方法
		public  void  dox(){
			//外部类中的方法中是不能访问方法内部类的。
			//InnerClass  inner=new InnerClass();
		}
		//外部类的类方法
		public static  void  doxStatic(){
			
		}
	
	
	public  void  test1(double num2){
		//test1方法中的局部变量
		int num1=100;
		//方法内部类---就相当于本方法中的局部变量
		//A 定义方法内部的时候没有访问修饰符
		//B 方法内部类中不能出现类变量和类方法
		//C 方法内部类可以访问本方法中的局部变量,jdk8.0之前需要使用final修饰局部变量,包括参数
		class  InnerClass{
			//方法内部类中的实例变量
			public int  innerid=1001;
			//方法内部类中不能有类变量
			//public static String  innername="1001";
			//方法内部类中的构造方法
			public  InnerClass(){
				//方法内部类中的构造方法,可以访问本方法中的局部变量,jdk8.0之前需要使用final修饰局部变量,包括参数
				System.out.println(num1);
				System.out.println(num2);
				//方法内部类中的构造方法,可以访问外部类的实例变量/实例方法,默认外部类类名.this. , 可以省略外部类类名.this.
				System.out.println(TestClass.this.testid);
				System.out.println(testid);
				TestClass.this.dox();
				dox();
				//方法内部类中的构造方法,可以访问外部类的类变量/类方法,默认外部类类名 ,
				//也可以外部类类名.this. ,可以省略外部类类名/外部类类名.this.
				System.out.println(TestClass.testname);
				System.out.println(TestClass.this.testname);
				System.out.println(testname);
				TestClass.doxStatic();
				TestClass.this.doxStatic();
				doxStatic();
			}
			//方法内部类中的实例方法
			public  void innerMethod(){
				//方法内部类中的实例方法,可以访问本方法中的局部变量,jdk8.0之前需要使用final修饰局部变量,包括参数
				System.out.println(num1);
				System.out.println(num2);
				//方法内部类中的实例方法,可以访问外部类的实例变量/实例方法,默认外部类类名.this. , 可以省略外部类类名.this.
				System.out.println(TestClass.this.testid);
				System.out.println(testid);
				TestClass.this.dox();
				dox();
				//方法内部类中的实例方法,可以访问外部类的类变量/类方法,默认外部类类名 ,
				//也可以外部类类名.this. ,可以省略外部类类名/外部类类名.this.
				System.out.println(TestClass.testname);
				System.out.println(TestClass.this.testname);
				System.out.println(testname);
				TestClass.doxStatic();
				TestClass.this.doxStatic();
				doxStatic();
			}
			//方法内部类中不能有类方法
			//public static void innerStaticMethod(){}
		}
		//在定义该方法内部类的方法中,访问方法内部类中的变量和方法,只能对象访问
		InnerClass inner=new InnerClass();
		System.out.println(inner.innerid);
		inner.innerMethod();	
	}
}

3.匿名内部类—类/抽象类/接口的子类

1.继承式的匿名内部类
例如:
package com.click369.test3;

public class TestMain {

	public static void main(String[] args) {
		//调用MyClass中的实例方法
		MyClass  mc=new MyClass();
		//当一个方法的参数是抽象类类型的时候,可以是传递子类对象、上转型对象
		//子类对象、上转型对象在创建的时候需要独立构建一个子类。
		//如果我偏不构建这个子类,还想调用这个参数是抽象类类型的方法,怎么办?????
		//可以使用匿名内部类的结构完成对子类的构建,只是现在构建出来的这个子类没有名称
		//所以才叫匿名内部类
		mc.myTest(new TestClass(){
			@Override
			public void testAbstractMethod() {
				System.out.println("重写抽象类中的抽象方法");
			}
		});
		/*
		 * 匿名内部类
		 new TestClass(){
			@Override
			public void testAbstractMethod() {
				
			}	
		   }
		上面的这种结构就是一个匿名内部类,它代表TestClass类的子类,只是这个子类没有名字
		 */
		//优点:可以有效的减少类的创建
		//缺点:不利于程序的阅读和理解
	}
}
2.接口式的匿名内部类
例如:
package com.click369.test4;

public class TestMain {

	public static void main(String[] args) {
		//调用MyClass这个普通类中的实例方法
		MyClass  mc=new MyClass();
		//当一个方法的参数为接口类型是,我们可以传递接口的子类对象/接口回调对象
		//子类对象/接口回调对象,都需要构建一个独立的子类。
		//如果我偏不构建这个子类,还想调用这个参数是接口类型的方法,怎么办?????
		//可以使用匿名内部类的结构完成对接口子类的构建,只是现在构建出来的这个接口的子类没有名称
		//所以才叫匿名内部类
		mc.dox(new MyInterface() {
			@Override
			public void test1() {
				System.out.println("重写接口的抽象方法");
			}
		});
		/*
		 * new MyInterface() {
			@Override
			public void test1() {
				System.out.println("重写接口的抽象方法");
			}
		   }
		   上面的这种结构就是一个匿名内部类,它代表MyInterface接口的子类,只是这个接口子类没有名字
		 */
		//优点:可以有效的减少类的创建
		//缺点:不利于程序的阅读和理解
	}
}

没有名字的内部类
4.静态嵌套类----就是成员内部类加上static修饰符
1.静态嵌套类中的元素
1.实例变量 2.类变量 3.构造方法 4.实例方法 5.类方法
2.静态嵌套类中的方法访问其他的变量和方法
1.在静态嵌套类中构造方法和实例方法中访问静态嵌套类中的实例变量/实例方法,默认this.,可以省略this.
2.在静态嵌套类中构造方法和实例方法中访问静态嵌套类中的类变量/类方法,默认静态嵌套类类名.,也可以省略this.,可以省略静态嵌套类类名./this.
3.在静态嵌套类中类方法中不能访问静态嵌套类中的实例变量/实例方法。
4.在静态嵌套类中的类方法中访问静态嵌套类中的类变量/类方法,默认静态嵌套类类名.,可以省略静态嵌套类类名.
5.在静态嵌套类中的类方法中不能出现this.
6.在静态嵌套类中构造方法和实例方法/类方法可以访问构造方法,通过new访问。
3.静态嵌套类中访问外部类的变量和方法
1.静态嵌套类中的构造方法/实例方法/类方法可以访问外部类的实例变量/实例方法,只能通过外部类的对象访问
2.静态嵌套类中的构造方法/实例方法/类方法可以访问外部类的类变量/类方法,默认外部类的类名.,可以省略外部类的类名.
3.静态嵌套类中的构造方法/实例方法/类方法可以访问外部类的构造方法,通过new访问
4.外部类中访问静态嵌套类中的变量和方法
1.外部类中的构造方法/实例方法/类方法中可以访问静态嵌套类中的实例变量和实例方法,通过对象访问。
2.外部类中的构造方法/实例方法/类方法中可以访问静态嵌套类中的类变量和类方法,默认静态嵌套类的类名访问,也可以使用对象访问 ,以省略类名。
3.外部类中的构造方法/实例方法/类方法中可以访问静态嵌套类中的构造方法,通过new访问。
5.其他类中访问静态嵌套类中的变量和方法
1.在其他类中可以访问静态嵌套类中的实例变量和实例方法,通过对象访问。
2.在其他类中可以访问静态嵌套类中的类变量和类方法,默认静态嵌套类的类名访问,也可以使用对象访问 ,以省略类名。
3.在其他类中可以访问静态嵌套类中的构造方法,通过new访问。
注意:以上的访问是需要导包语句
import 包名.外部类类名.静态嵌套类的类名;
6.2异常类的体系结构?Error和Exception的区别?
java中的异常【Exception】和错误【Error】都是Throwable的子类。
public class Exception extends Throwable{}
public class Error extends Throwable{}

区别:
error:表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception:表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。
6.3运行时异常与非运行时异常?
5.异常【Exception】又有2大类构成
1.运行时异常—程序编写的时候没有异常,在运行的时候才会出现的异常
2.非运行时异常—我们在编写程序的时候,就已经出现的异常。
在这里插入图片描述

6.4如何处理异常?Try{}catch(){} throws throw finally
1.使用try{}catch(异常类型){}捕获处理异常。

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		int a=10;
		int b=0;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
	}
}

运行结果:
在这里插入图片描述
当我们没有使用try{}catch(){}捕获处理异常的时候,默认java程序会将这个程序中的异常输出到控制台上。

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int  a=10;
		int b=0;
		int c=a/b;
		System.out.println("c=="+c);
		}catch(Exception e){
			System.out.println("处理异常的程序");
		}
	}
}

当我们使用try{}catch(){}捕获处理异常以后,那么程序出现异常以后会执行我们的异常处理程序。
在这里插入图片描述

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int  a=10;
		int b=0;
		int c=a/b;
		System.out.println("c=="+c);
		}catch(Exception e){
//打印堆栈异常信息到控制台
			e.printStackTrace();		
}
	}
}

当我们不想处理这个异常的时候,也可以通过try{}catch(){}将异常信息输出到控制台。
e.printStackTrace();//打印堆栈异常信息到控制台
在这里插入图片描述
结构:
try{
可能出现异常的java代码
}catch(异常类型){
捕获,处理异常
}
try{}catch(){}捕获处理异常的过程:
将可能出现异常的java代码使用try{}包围,当try{}中的java代码出现异常,程序就会立刻停止运行,转而执行try{}后面的catch(异常类型){}中的内容,catch块就是书写处理异常的代码。
在这里插入图片描述
1.try{}catch(异常类型){}中的catch中的异常类类型,往往是需要一个具体的异常类型。
例如上面的实例中输出的“java.lang.ArithmeticException”就是一个除数为0的具体异常类型

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int a=10;
		int b=0;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
		}catch(ArithmeticException th){
			System.out.println("catch块捕获处理异常");
			//打印堆栈异常信息
			th.printStackTrace();
		}
	}
}

但是我们往往不知道这种具体的异常类型是什么,我们就可以使用Exception或Throwable代替具体异常类型。

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int a=10;
		int b=0;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
		}catch(Throwable th){
			System.out.println("catch块捕获处理异常");
			//打印堆栈异常信息
			th.printStackTrace();
		}
	}
}
或者
package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int a=10;
		int b=0;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}

为什么可以使用Exception或Throwable代替具体异常类型?
Exception是所有具体异常类型的父类,Throwable是Exception的父类。
2.一个try{}后面可以出现多个catch(异常类型){}。当出现多个catch(异常类型){}的时候根据catch中的异常类型按照异常类型的级别从小到大排列。
区分异常类型的级别大小,看异常类型的继承关系
Throwable异常的顶级类,有一个子类Exception,Exception有很多的子类 ArithmeticException 是Exception众多子类中的一个。
由小到大的级别排列:
ArithmeticException Exception Throwable

Public  class  Throwable{

}
Public  class  Exception  extends Throwable{

}
Public  class  ArithmeticException    extends  Exception  {

}

例如:
package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int a=10;
		int b=0;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
		}catch(ArithmeticException e){
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}catch(Throwable th){
			th.printStackTrace();
		}
	}
}

3.finally{}块出现在最后一个catch块的后面,程序有没有异常都会被执行的部分。

package com.click369.test1;
public class TestMain {
	public static void main(String[] args) {
		try{
		int a=10;
		int b=1;
		int c=0;
		c=a/b;
		System.out.println("c=="+c);
		}catch(ArithmeticException e){
			e.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}catch(Throwable th){
			th.printStackTrace();
		}finally{
			System.out.println("程序有没有异常都要执行的部分");
		}
	}
}

6.5常见的异常?
1.java.lang.nullpointerexception 异常的解释是"程序遇上了空指针"
2.java.lang.classnotfoundexception 异常的解释是"指定的类不存在"
3.java.lang.arithmeticexception 这个异常的解释是"数学运算异常"
4. java.lang.arrayindexoutofboundsexception 异常的解释是"数组下标越界"
5. java.lang.illegalargumentexception 这个异常的解释是"方法的参数错误"
6. java.lang.illegalaccessexception 这个异常的解释是"没有访问权限"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值