内部类
使用内部类的时候必须要导包
里面包裹的类 : 内部类
外面的类: 外部类, 宿主类
四类:
* 成员内部类
* 静态内部类
* 局部内部类
* 匿名内部类
内部类创建方式 要通过 外部类对象创建内部类对象
发动机 f = car.new 发动机();
发动机 f2 = new Car().new 发动机();
f2.type = "345";
f2.work();
成员内部类
1.可以使用四种访问权限修饰符修饰的
2.局部变量是不能用static修饰的
3. 使用内部类的时候必须要导包
4.内部类是可以使用外部类的属性和方法的, 包括私有的
5. 内部类属性和外部类属性同名的时候, 优先使用的 内部类的
即使用this也是使用的内部类的, 除非创建外部类对象调用
6.内部类字节码文件命名方式 外部类$内部类.class
public class Car {
String color = "绿色的";
private void run(){
System.out.println("跑");
}
public class 发动机{
String color = "红色的";
String type;
public void work(){
System.out.println("发动机");
run();// 3.内部类是可以使用外部类的属性和方法的, 包括私有的
System.out.println(new Car().color);// 4. 内部类属性和外部类属性同名的时候, 优先使用的 内部类的
// 即使用this也是使用的内部类的, 除非创建外部类对象调用(new Car().color)
}
}
}
静态内部类
1. 静态内部类中可以使用静态的属性和方法
2. 静态内部类可以直接创建对象 不需要外部类对象
3. 静态内部类中 不能直接使用外部类的非静态的属性和方法
4. 内部类中的属性和外部类属性同名的时候, 可以通过外部类.静态属性 调用外部类属性
5. 字节码文件的名字 外部类$内部类.class
public class Outer {
static String name;
int age;
public void run(){
System.out.println("跑");
}
// 静态内部类
// 1. 静态内部类中可以使用静态的属性和方法
// 5. 字节码文件的名字 外部类$内部类.class
static class Inner{
int a;
static int b;
static String name;
//3. 静态内部类中 不能直接使用外部类的非静态的属性和方法
public void a(){
System.out.println("a");
//4. 内部类中的属性和外部类属性同名的时候, 可以通过外部类.静态属性 调用外部类属性
System.out.println(Outer.name);
//System.out.println(age);
}
public static void b(){
System.out.println("static 的b");
}
}
}
// 测试类
public static void main(String[] args) {
// 2. 静态内部类可以直接创建对象 不需要外部类对象
Inner inner = new Inner();
}
局部内部类
类似于一个局部变量
字节码文件的名字 外部类$数字内部类名字.class
1. 局部内部类定义在方法内部的类
2. 不能使用访问权限修饰符以及 static进行修饰
3. 局部内部类中可以使用 外部类的属性也可以使用方法中的局部变量
4. 如果局部内部类中的属性和外部类成员属性同名, 则可以使用外部类.this.属性 调用外部类的属性
5. 局部内部类只能在声明此内部类的方法中创建对象
6. 局部内部内部类只能方法被调用的时候,才能执行
public class Test {
int a = 3;
public static void main(String[] args) {
Test test = new Test();
test.test();
}
public void test(){
int age = 3;
// 局部内部类 类似于一个局部变量
// 3. 局部内部类中可以使用 外部类的属性也可以使用方法中的局部变量
class Inner{
public String name= "mingzi";
private int a = 5;
public void show(){
System.out.println(name);
System.out.println(age);
//4. 如果局部内部类中的属性和外部类成员属性同名, 则可以使用外部类.this.属性 调用外部类的属性
System.out.println(Test.this.a);
}
}
// 5.局部内部类只能在声明此内部类的方法中创建对象
Inner inner = new Inner();
inner.show();
// 6. 局部内部类只有方法被调用的时候,才能执行
}
}
匿名内部类
1. 没有自己本类的名字, 只能拿接口或者抽象类的名字代表
2. 创建的是实现类或者子类的对象
3. 左边是接口的名字 = 右边是实现类的对象 向上转型
4. 即使一个内部类或者接口 ,new了多次, 是多个实现类
5. 当有实现类或者子类只需要创建一次对象,则可以使用匿名内部类. 可以使程序结构更加简洁
6. 匿名内部类的名字 外部类$数字.class
其他类、接口:
public class Anaiml implements Run{
public void run() {
System.out.println("动物跑步");
};
}
public class Person implements Run{
@Override
public void run() {
System.out.println("人跑步");
}
public void eat(){
}
}
public abstract class AbstractClass {
public abstract void b();
}
public interface Run {
public void run();
}
public class Test3 {
public static void main(String[] args) {
Person person = new Person();
person.run();
Anaiml anaiml = new Anaiml();
anaiml.run();
Run run = new Run() {
@Override
public void run() {
System.out.println("外星人跑步");
eat();
}
// 匿名内部类中可以额外定义自己的方法, 但是一般不这样做
public void eat(){
}
};
run.run();
//run.eat(); --> ((Person) run).eat();
// 创建抽象类对象 内部类
AbstractClass class1 = new AbstractClass() {
@Override
public void b() {
System.out.println("bbb");
}
};
class1.b();
}
}
异常
如果出现异常,会自动生成一个异常类对象
程序: 如果发生了异常
* 先执行try 代码块
* 发现异常,jvm自动的创建异常的对象
* 查找能够捕获异常的代码找catch
* 如果catch中的类型和异常类型匹配则执行catch块进行处理异常
* 程序继续向下执行,不会中断
* 如果catch中类型不匹配,则直接爆出异常, 让程序中断
*
* 如果没有发生异常:
* 先执行try块
* 如果没有异常则执行完try以后 不执行catch finally总是执行
一个try可以对应多个catch, 父类必须写在子类的下面
try{
int i = 10/0;
String string = null;
string.length();
// 关闭
}catch (NullPointerException e) {
System.out.println("发生了空指针异常");
}catch(ArithmeticException e){
System.out.println("发生了算数异常");
}catch (ArrayIndexOutOfBoundsException e) {
System.out.println("下标越界异常");
}catch (ClassCastException e) {
System.out.println("类型转换异常");
}catch (Exception e) {
System.out.println("发生了异常");
}finally{
// 无论是否发生异常 都会执行此代码
// 资源清理和关闭的操作
}
try{
//finally 只有直接退出系统 才不执行 否则一定会执行 即使 return break也必须要执行
System.exit(0);;// 不执行
}finally {
System.out.println("aaa");
}
常见的异常
运行时异常
NullPointerException 空指针
String string = null;
string.toString();
ArrayIndexOutOfBoundsException 数组下标越界
int[][] arr = new int[][]{{1,2},{3,4}};
arr[0][0] = 6;
arr[1][1]= 8;
arr[2][2] = 5; // 异常
ArithmeticException 算数异常
by zero 除数为0
//ArithmeticException 算数异常
// by zero 除数为0
int i= 10/0;
System.out.println(i);
非运行时异常
编译时期就会报错,必须处理,不处理就无法运行 涉及到外界资源, 有可能会因为外界资源的改变导致 出现问题,
无论是否发生异常都要求处理以后才能执行 , 在编译实际就会 提示
文件找不到
File file = new File("C:/aa/bb/a.txt");
try {
file.createNewFile();
} catch (IOException e) {
System.out.println("aaaa");
}
System.out.println("bbb");
throws
throws 异常发生的可能性 , 声明异常
throws 可以跟多个异常类型, 标明方法内部可能存在异常, 如果发生异常 将异常转给调用者
标明异常存在的可能性 抛出 写在方法声明后面
public static void a() throws ArrayIndexOutOfBoundsException,ArithmeticException{
int i = 10/1;
int[] arr={1,2,3,4};
System.out.println(arr[3]);
}
throw
只要出现了throw 通常会结合throws 使用
throw new NullPointerException();// 产生异常 抛出异常 , 方法内部的, 跟的是异常对象, 只能跟一个
public static void b() throws NullPointerException{
for(int i = 0; i<5;i++){
if(i==3){
// throw 后面跟的是异常对象, 真正产生异常
throw new NullPointerException();// 产生异常
}
System.out.println(i);
}
}
自定义异常
如果想要自定义非运行时异常 继承Exception
public class LegException extends Exception{
public LegException() {
super();
// TODO Auto-generated constructor stub
}
public LegException(String message) {
super(message);
// TODO Auto-generated constructor stub
}
}
只有继承了RuntimeException 才是运行时异常
public class SexException extends RuntimeException{
public SexException() {
super();
}
public SexException(String message) {
super(message);
}
}
异常总结
1. 异常体系中:
* Thrwable
* Error: 严重性错误, 没有办法直接解决, 只能尽量避免
* Exception : 异常,通常都是逻辑错误导致的 , 可以解决
2. 异常的处理机制:
* 当发生异常的时候,会产生异常对象, 去查找处理异常的代码, 如果找到则交由其处理, 程序正常运行
* 没有找到则 程序终止
3. 异常的分类:
* 运行时异常(非受检异常)
* 非运行时异常(受检异常,编译时异常)
4. 处理异常的方式
* try
* catch
* finally
5. throw 和throws
* throws 异常发生的可能性 , 声明异常 , 写在方法声明后面 , 跟的异常类型,可以跟多个
* throw new NullPointerException();// 产生异常 抛出异常 , 方法内部的, 跟的是异常对象, 只能跟一个
* 只要出现了throw 通常会结合throws 使用
异常面试题
Java中的两种异常类型是什么?他们有什么区别?
Java中有两种异常:受检查的(checked)异常和不受检查的(unchecked)异常。不受检查的异常不需要在方法或者是构造函数上声明,就算方法或者是构造函数的执行可能会抛出这样的异常,并且不受检查的异常可以传播到方法或者是构造函数的外面。相反,受检查的异常必须要用throws语句在方法或者是构造函数上声明。
Java中Exception和Error有什么区别?
Exception和Error都是Throwable的子类。Exception用于用户程序可以捕获的异常情况。Error定义了不期望被用户程序捕获的异常。
throw和throws有什么区别?
throw关键字用来在程序中明确的抛出异常,相反,throws语句用来表明方法不能处理的异常。每一个方法都必须要指定哪些异常不能处理,所以方法的调用者才能够确保处理可能发生的异常,多个异常是用逗号分隔的