------- android培训、java培训、期待与您交流! ----------
内部类, 异常
内部类
1. 内部类是在一个类的内部再声明一个类,这个类能访问所在外部类的成员变量, 声明内部类的方法有两种,一种是在成员位置上, 另一种是在方法内
2. 声明在成员位置
1) 非static内部类
语法格式代码示例
package com.itcast.review;
public class ExtTest {
public static void main(String[] args) {
A.B ab = new A().new B(); // 直接创建内部类对象的
ab.show();
A a = new A();
a.printInner(); // 通过外部类对象的方法调用内部类
}
}
class A {
int c = 5;
// 声明一个非静态的内部类
class B {
int c = 10;
void show() {
int c = 20;
System.out.println(c); // 内部类方法访问方法内部的变量
System.out.println(this.c); // 内部类访问内部类的成员变量
System.out.println(A.this.c); // 内部类访问所在外部类的成员变量
}
}
// 访问内部类对象
void printInner() {
B b = new B(); // 创建内部类对象
b.show();
}
}
注意:在其它类中穿件内部类对象格式是 OuterClass.InnerClass in = new OuterClass().new InnerClass();当外部类的成员属性和内部类的成员属性重名时, 访问外部类的格式是 Outer.this.属性;
1) static内部类
语法格式代码示例
package com.itcast.review;
public class ExtTest {
public static void main(String[] args) {
A.B ab = new A.B(); // 直接创建内部类对象的
ab.show();
A a = new A();
a.printInner(); // 通过外部类对象的方法调用内部类
}
}
class A {
static int c = 5;
// 声明一个非静态的内部类
static class B {
static int c = 10;
void show() {
int c = 20;
System.out.println(c); // 内部类方法访问方法内部的变量
System.out.println(this.c); // 内部类访问内部类的成员变量
System.out.println(A.c); // 内部类访问所在外部类的成员变量
}
}
// 访问内部类对象
void printInner() {
B b = new B(); // 创建内部类对象
b.show();
}
}
注意: 关于内部类声明在成员位置上时它的static修饰的问题
1) 如果内部类使用static修饰,在内部类中就不能直接访问外部类的非static成员
2) 如果内部类中有static成员,内部类必须使用static修饰
3) 如果内部类使用static修饰,那内部类的成员可以是static,也可以不是.
1. 声明在方法内
声明在方法内的内部类可以访问所在外部类的成员属性,访问所在方法内的变量必须是final修饰的,因为方法内的变量在使用完就消失了, final修饰的是常量,声明周期跟类一样
方法内的内部类对象只在方法内声明有效
语法格式代码示例
package com.itcast.review;
public class InnerClassTest {
public static void main(String[] args) {
// 创建一个Outer对象
Outer o = new Outer();
// 调用Outer对象的show方法
o.show();
}
}
// 定义一个外部类
class Outer {
int d = 20;
// 创建一个包含内部类的方法
void show() {
final int a = 10; // 内部类只能访问方法内用final修饰的局部变量
class Inner {
int b = d; // 内部类的成员属性
void getSum() { // 内部类中的方法
int sum = a + b;
System.out.println(sum);
}
}
Inner in = new Inner();
in.getSum();
}
}
匿名内部类
1. 内部类的一种简化写法
2. 格式
new 类名|接口名([参数]){
//属性-------->很少使用
//方法-------->可以是自定义方法但是绝大多数情况下都是重写的方法。
};
new 代表创建一个匿名内部类对象
类名|接口名 代表的是匿名内部类继承的父类或实现的接口
{} 它代表的是匿名内部类的内容.
3. 笔试题
Objectobj=new Object(){
publicvoid show(){
System.out.println("show....");
}
};
obj.show();//父类引用指向子类对象不能调用子类特有的方法
newObject(){
publicvoid show(){
System.out.println("show....");
}
}.show();//子类对象调用自己的方法
匿名内部类一般都是将其做为一个参数进行传递
异常
1. 异常就是程序中存在的问题,这种问题我们可以解决
下面这段代码访问了数组中不存在的位置,编译时没有出现问题, 运行时会产生一个ArrayIndexOutOfBoundsException异常
public class Test {
public static voidmain(String[] args) {
int[] arr ={1, 4, 5, 6, 7, 8};
int a =arr[arr.length];
System.out.println(a);
}
}
运行结果
Exception in thread "main"java.lang.ArrayIndexOutOfBoundsException: 6
atcom.itcast.review.Test.main(Test.java:7)
1. 程序中遇到的问题分为两种
Exception(异常):我们必须处理的异常
Error(错误):我们不处理
这两个类都是Throwable的子类
2. Exception下面有一个RuntimeException
RuntimeException以及其所有子类都是运行异常,除了RuntimeException及其子类外的所有类都是编译异常
3. 对于异常的处理方式
1) 捕获 try-catch-finally 2.
语法格式
try {
可能抛出异常的语句
}
catch (Exception e) {
处理异常语句或者抛出一个新异常
}
2) 抛出 throws
当方法中出现异常可以在方法名后面用这个关键字将异常抛出
语法
public void method() throws Exception {
可能抛出异常的代码
}
无论是什么异常都可以使用上述两种行为人对其进行操作
但是对于编译异常, 在代码上就强制要求必须对其进行处理, 而对于运行异常,我们在代码上没有强制要求,可以不用处理
4. throws和throw关键字
1) 这两个关键字都是用来抛出异常
2) throw与throws区别
throws 它是用来标识一个方法是否抛出异常
throw 它的作用是抛出一个异常对象
a) throws写在方法的后面
throw 写在方法中
b) throws后面写的异常类的名称
throw 后面写的是一个异常对象 new XxxExcetpion();
c) throws后面可以加多个异常名称
throw后面只能有一个异常对象.
5. 自定义异常:只要定义一个类继承Excption就可以
6. 在进行重写时异常的注意事项
1) 对于重写的方法来说,父类中的方法如果抛出了异常, 那么子类可以不抛出,如果要抛出只能与父类一样的异常或父类异常的子集
2) 如果父类中方法没有抛出异常,子类重写方法中产生了异常, 好么只能在重写的方法内捕获,而不能抛出
7. Finally关键字
无论try块中是否产生异常, finally中的内容永远会被执行到, finally块中在实际开发中一般完成关闭动
例如: 在进行IO读写操作的时候,需要打开设备的读入和写出的通道, 如果不关闭会消耗很多资源,所以将关闭IO的操作放到finally语句块中,无论读写时是否出现异常, 关闭IO的语句都会执行
8. 一个try{}可以对应多个catch () {}, 对于try块产生的可能是不同的异常, catch每次只能处理一个异常,这个时候就可以多定义几个catch语句用于处理try内产生的不同的异常
异常代码示例
一个课上的小练习, 老师的电脑出现了蓝屏, 冒烟的异常
/*
分析: 1. 实体: 老师, 电脑
2. 电脑不正常的情况: 蓝屏, 冒烟
3. 蓝屏异常, 重启可解决, 冒烟, 彻底报废, 不可解决
4. 蓝屏异常重启解决, 冒烟需要换老师上课
*/
class TeachTest {
public static void main(String[] args) {
// 创建电脑的对象
Computer computer = new Computer();
// 创建老师的对象
Teacher teacher = new Teacher();
// 老师操作电脑, 捕获异常
try {
teacher.operate(computer);
} catch (ChangeException e) {
System.out.println(e.getMessage() + " 换个老师来上课");
}
}
}
// 定义一个老师的实体类
class Teacher {
// 老师的属性
String name = "张三";
// 老师操作电脑的方法
void operate(Computer p) throws ChangeException {
System.out.println(name + "老师将要用电脑上课");
try {
p.run();
}
// 捕获蓝屏异常
catch (BuleScreenException e) {
System.out.println(e.getMessage() + name + " 老师可以解决");
// 重新启动
p.restart();
operate(p);
}
// 捕获冒烟异常
catch (MaoYanException e) {
System.out.println(e.getMessage() + name + "老师无法解决这个问题");
throw new ChangeException(e.getMessage() + name + "老师无法上课了");
}
}
}
// 定义一个电脑的实体
class Computer {
// 电脑的状态
int state = 1;
// 电脑启动方法
void run() throws BuleScreenException, MaoYanException {
System.out.println("老师启动电脑");
// 状态是0, 正常启动
if (state == 0) {
System.out.println("电脑正常启动");
}
// 状态是1, 抛出蓝屏异常
if (state == 1) {
throw new BuleScreenException("电脑蓝屏了");
}
// 状态是2, 抛出冒烟异常
if (state == 2) {
throw new MaoYanException("电脑冒烟了");
}
}
// 重新启动方法
void restart() {
System.out.println("电脑被重启");
// 状态重置为0
state = 0;
}
}
// 定义一个蓝屏的异常
class BuleScreenException extends Exception {
// 重写构造方法
public BuleScreenException(String message) {
super(message);
}
}
// 定义一个冒烟的异常
class MaoYanException extends Exception {
// 重写构造方法
public MaoYanException(String message) {
super(message);
}
}
// 定义一个老师无法上课的异常
class ChangeException extends Exception {
public ChangeException(String message) {
super(message);
}
}
包
1. Java中的包为类提供了多层命名空间,是用来管理类的
2. 语法格式
package com.xxx.xxx;
一般是把公司的域名反转, 包名都是小写的, 必须写在第一行,并且只能写一句
3. 在访问其它包的类时,应该先将那个类的包导入, 语法是import包名.类名,或者使用时类的前面加上包名, 语法是包名.类名
访问权限(重点)
1. Java中的4中访问权限
同一类内 同一包内 包外子类 不同包中
private ok
默认 ok ok
protected ok ok ok
public ok ok ok ok