JAVA中的 数据处理

111 阅读24分钟

JAVA中的 数据处理

1.接口:

1.接口的基本介绍:

1.接口就是给出一些没有实现的方法,封装到一起,到某个类使用时,再根据具体情况把这些方法给写出来;
接口也是一个类!!!!!!!!!!!!1
接口相当于定义好规范(方法),然后让类来实现它们!!!!!!!@
2.语法:

(1.)接口定义:!!!
.interface 接口名{
   属性(都是public static final修饰);
   方法;
   a:可实现的方法:但必须在最前面加上default
   b:可以有静态方法:(不用加default)
   c:抽象方法:在接口中抽象方法可以不写abstract,默认为抽象方法;!!
}
(2.)子类实现接口的方法!!!
.class 类名 implements接口{
      自己的属性;
      自己的方法;
      必须实现的接口的抽象方法;!
}

3.如果一个类要实现(implement)接口:需要将该类的所有抽象方法都实现;!!!

4.接口使用:定义一个接口,然后在子类实现接口中的方法!!!

2.演示案例:

package interface2;

//接口的应用场景!!!

 //项目经理写的接口!
public interface DBinterface {//项目经理:写了两个方法,要求两个人实现不同的功能;

  public void open();

  public void close();
}
package interface2;
//A程序员做的工作:实现A功能
public class EmployA implements DBinterface{//实现接口的方法:open,close
    public void open(){
        System.out.println("实现打开功能A");
    }
    public void close(){
        System.out.println("实现关闭功能A");
    }
}
package interface2;
//B程序员:实现B功能
public class EmployeeB implements DBinterface{//实现接口方法

    public void open(){
        System.out.println("实现打开功能B");
    }

    public void close() {
        System.out.println("实现关闭功能B");
    }
}

package interface2;
//接口使用场景!!!!!!!!!!!!!!!!
public class Test {//Class类

    public static void main(String[] args) {
        //如果想要连接EmployeeA,直接new它的对象,然后传进去对象
        EmployA employA=new EmployA();
        t(employA);//调用t方法

        EmployeeB employeeB=new EmployeeB();
        t(employeeB);//调用t方法

    }
    public static  void  t(DBinterface dBinterface){////创建方法:使用接口调用来实现)接口的方法
        // 将接口类的属性传进去,因为其它类实现接口相当于继承了接口,即可以理解为接口是父类,
        // 使用向上转型,将接口(父类)的对象传进去,所以子类对象都可以直接传进去;

        //解释:
        // 创建静态方法:因为main为静态,
        // 静态方法只能调用静态成员!!!!!!!!!!!!
        // 使用接口调用(实现)接口的方法,然后传入形参,!!!!!!!!!!!
        // 传入的是谁,就自动调用谁的对应方法
        dBinterface.open();//调用open方法

        dBinterface.close();//调用close方法
    }
}

2.内部类:

1.内部类简介·:

内部类基本介绍:
1.a:一个类的内部又完整的(5个成员)嵌套了另一个类结构。被嵌套的类称为内部类(inter class),嵌套其它类的类称为外部类(outer class)
是类的5大成员之一;
  b:类的5大成员之一:属性,方法,构造器,代码块,内部类;
  c:!!!内部类最大的特点:可以直接!访问外部类所有的成员(包含外部类的私有成员(因为在一个外部类中)),
  并且可以体现类与类之间的包含关系;
  d:本质仍然是类;可以被继承等
2.基本语法:
class Outer{//外部类(类名)
     class Inter{//外部类

     }
}
class Other{//(外部)其他类

}
3.演示快速入门:下面的代码

4.内部类的分类(4种):
一:定义在外部类的 局部 位置上 (比如方法内)
   1.局部内部类(有类名);
   2.匿名内部类(无类名);!!!!!!!!!!!!!!!!!!!!!:用的最多最重要!!!!!!!!!
二:定义在外部类的  成员 位置上 (比如属性,方法的位置)
   1.成员内部类(没用static修饰);
   2.静态内部类(使用static修饰);

2.局部内部类:

1.局部内部类简介:
!局部内部类(有类名);定义在外部类的 局部 位置上
演示:使用

局部内部类:细节1
.位置说明:局部内部类是定义在外部类的局部位置,比如方法中或者代码块中,并且有类名。!!!
1可以直接访问外部类的所有成员,包括私有!
2.局部内部类不能使用修饰符,但可以使用final修饰(就不可被继承了)
(类本身可以有public m默认修饰,但是局部内部类是一个局部变量,局部变量本身不能被修饰符修饰)
3.局部内部类的作用域:!!!:仅仅可在定义它的方法体,或代码块中使用。(因为局部)
4.a:局部内部类要访问外部类的成员(属性,方法):!!直接访问!!
  b:外部类要访问局部内部类的成员:在外部类的!方法中!new内部类的对象,然后调用即可.
5.本质仍然是一个类

细节21.外部其它类不能访问局部类(因为局部内部类地位是一个局部变量);
2. a:如果外部类和局部内部类的成员重名时,默认遵循就近原则
   b:但如果仍想要访问外部类的成员:使用 外部类名.this.成员 去访问;
   解读:Outer0.this本质就是外部类的对象,哪个对象调用m1方法(内部类在m1方法中)
    Outer0.this就是哪个对象;
 */
2.局部内部类演示:
public class InterClass02 {
    public static void main(String[] args) {
        Outer0 outer0=new Outer0();
        outer0.m1();

    }
}
class Outer0{
    private int n1=10;//外部类私有属性

    private void m(){
        System.out.println("m()");
    }
    public void m1() {//外部类方法:在方法中创建外部类!
        
        class Inner {//内部类(也可以拥有完整5大成员):
            private int n1 = 15;//内部类属性;

            public void m2() {//内部类方法
                //内部类可以直接访问外部类所有成员(包括私有!!!)
                System.out.println("n1="+n1);//访问内部类私有属性
                m();//访问内部类私有方法;


                //但如果仍想要在访问到外部类的成员:外部类名.this.成员 去访问
                System.out.println("外部类的n1="+Outer0.this.n1);
                //解读:Outer0.this本质就是外部类的对象,哪个对象调用m1方法(内部类在m1方法中),
                // Outer0.this就是哪个对象;
            }
        }
        //外部类要访问局部内部类:在外部类方法中new内部类的对象
        Inner inner=new Inner();
        inner.m2();

        //class Inner02 extends Inner{}//内部类之间可以继承
    }
}

3.匿名内部类:(!!!)

1.匿名内部类简介:
//匿名内部类(Anonymous innerclass)!!!!!!!!!!!重点难点·,使用最多的!!!

//匿名内部类本质!!!!
/*
1.(1.)本质仍是类,(2.)位置:在外部类 局部位置(方法,代码块)上,是内部类,(3.)该类没有名字(看不到)
(4.)匿名内部类同时也是对象!!!!!!!!!!!!!!!

2.匿名内部类基本语法:
new 类/接口(参数列表){---->:参数列表到时候可以和构造器用!!!
      类体
};

3.演示:


一.基于接口的匿名内部类

传统方法:写一个类,实现该接口,创建对象;
缺点:Tiger只使用一次,后面不再使用,那样会定义很多类,繁琐且浪费类;

!!既不创建Tiger类,又可以使用cry方法:所以我们可以使用匿名内部类来简化开发
2.匿名内部类案例演示:
public class InterClass03 {
    public static void main(String[] args) {
       Outer04 outer04=new Outer04();//直接创建外部类的对象
       outer04.method();//调用方法即可
        /*IA tiger=new Tiger();
        tiger.cry();*/

    }
}


class Outer04{//外部类
    private int n1=10;
    public void method(){//方法!

        IA tiger=new IA(){//匿名内部类接口!!!!,
            //tiger的编译类型:IA,运行类型是:匿名内部类Outer04$1(隐藏)!!!!!!!

            public void cry(){//(匿名内部类(接口))重写了cry方法!!!1

                System.out.println("老虎叫");
            }
        };
        tiger.cry();//!!!调用接口的方法:因为外部类不能直接访问内部类的方法:需要new对象再调用
        //但是已经new对象了,所以直接调用即可!!

        //底层代码:
           /* 底层代码:会分配一个类,来实现接口;
            ==eg class Outer04$1 implements IA{
              public void cry(){
               System.out.println("老虎叫");
               }
            }*/
        //!!!!new:在创建了匿名内部类Outer04$1后,立即就创建了(IA接口)匿名内部类的实例对象
        // 并把地址返回给tiger;


        //二:演示基于多态参数的匿名内部类
        //jack会自动传给Father的构造器
        Father father=new Father("jack"){//创建匿名内部(类的)=对象!!:加了“{}”!!! // (原本为创建Father类的对象)
            //!!因为有一个new,所以创建一个(匿名内部类Outer04$02)的对象,使用father接收!
            //编译类型:Father(父类),运行类型:”=“右边其实是:Outer04$02(隐藏)!!!
            public void test(){
                System.out.println("匿名内部类重写了test方法");
            }
        };
        father.test();//!!因为返回给了(相当于父类)对象father,所以直接使用father对象调用方法;

        /*
        ==底层代码:分配一个类来继承Father类
        class Outer04$02 extends Father{
               public void test{
               System.out.println("匿名内部类重写了test方法");
               }
        }
         */

        //三:基于抽象类(abstract Animal)的匿名内部类:

        Animal animal=new Animal(){//创建匿名内部类Outer04$03(或它的对象)
            //!!因为有一个new,所以同时返回了一个对象(匿名内部类Outer04$03)的对象,并返回给animal
            //!!!分析:编译类型:Animal,运行类型:Outer04$03(隐藏了)
            void eat(){
                System.out.println("小狗狗吃骨头");//抽象类方法必须实现
            }
        };
        animal.eat();
        /*
        ==底层代码:分配一个类来继承抽象类:Aniaml;
        class Outer04$03 extends Animal{
             void eat(){
                System.out.println("小狗狗吃骨头");//抽象类方法必须实现
            }
        }
         */
    }

}
interface IA{//接口IA
    public void cry();
}

/*class Tiger implements IA{
    public void cry(){
        System.out.println("tiger叫");
    }
}*/
class Father{
    private String name;
    public Father(String name){//构造器
        this.name=name;
    }
    public void test(){//方法
    }
}
abstract class Animal{//三:抽象类
    abstract  void eat();//抽象方法:需要类的子类的实现;!!!
}
3.匿名内部类注意细节:
//匿名内部类的使用细节及注意事项:
/*
1.匿名内部类的语法
2.匿名内部类:既是类又是对象!!!(因为前面有new)!!!!
因此它 既有定义类的特征( ”{}“ ),又有创建(new)对象的特征。
3.!!!!演示:调用匿名内部类方法的两种方式:1 2
1.Person person=new Person(){// 编译类型:Person,运行类型Outer05$05
            public void hi(){
                System.out.println("匿名内部类重写了hi方法");//
            }
        };
        person.hi();//+++++++方法1



4.匿名内部类可以直接访问外部类的所有成员(包括私有)。
5.匿名内部类不能添加访问修饰符,因为它的地位是局部变量
6.匿名内部类作用域:只能使用一次,仅在定义它的方法或代码块中/
7.外部其它类 不能访问 匿名内部类(因为匿名内部类的地位:局部变量:只能使用一次)
8.如果外部类和匿名内部类成员重名,!在匿名内部类中!访问时,访问遵循就近原则。
 但如果仍想要在在!匿名内部类中!访问外部类的重名成员:则  :外部类类名.this.成员。eg:Outer05.this.n1;
 eg:Outer05 outer05=new Outer05
     outer.f1();
     谁调f1(),Outer05.this就是指的是外部类的对象(哪个对象调用):在这里就是指的outer05!!!!
public class InterClass05 {
    public static void main(String[] args) {//main方法
        Outer05 outer05=new Outer05();
        outer05.f1();
    }
}
class Outer05{//外部类
    private int n1=99;
    public void f1(){//创建一个方法:用于创建一个匿名内部类


        //四演示:创建一个基于类(Person)的匿名内部类;!!!
        Person person=new Person(){// 编译类型:Person,运行类型Outer05$05。
           /* private int n1=88;*/
            public void hi(){
                System.out.println("匿名内部类重写了hi方法");//
                /*System.out.println(n1);//直接访问外部类的私有成员*/
            }
        };
        person.hi();//+++++++++++++方法1
        // 动态绑定机制,看运行类型:真实的运行类型:Outer05$05,所以会先从Outer05$05
        //类(即上方的匿名内部类)中找hi方法,如果有且可以访问就调用,如果没有就看Person类中



        new Person(){//+++++++++++方法2:newPerson就是匿名内部类的对象,所以最后直接调用hi()即可
            public void hi(){//重写Person类方法1
                System.out.println("匿名内部类重写了hi方法hhhhhh");//
            }
            @Override
            public void ok(String str) {//重写方法2
                super.ok(str);
            }
        }.ok("jack");
              //或者.hi();//动态绑定机制
    }
}

class Person{//类
    public void hi(){//方法
        System.out.println("Person hi()");
    }
    public void ok(String str){//方法
        System.out.println("Person ok"+str);
    }
}

//还可以有抽象类,接口,和04中的一样,这里不演示!!!!!

4.成员内部类

1.成员内部类简介
二:1.成员内部类:->是成员!!!

(1.快速入门)
1.定义位置:定义在外部类的成员位置上;!!!
2.成员内部类可以被任意修饰符修饰(因为它是成员变量)。
3.成员内部类的作用域:和外部类的其它成员一样,为整个类体(因为定义在外部类中)。
(!!!!!)访问方式:在外部类的方法中创建内部的对象,再调用方法;
4.访问:a:成员内部类-->访问外部类:直接访问所有成员;
       b:外部类  --->访问成员内部类:在外部类的方法中创建内部的对象,再调用相关属性方法!!
2.演示:
public class Memberinnerclass {
    public static void main(String[] args) {
        Outer08 outer08=new Outer08();//创建外部类的对象;
        outer08.show();//调用外部类方法show;

        //!!!方法1:new Inner08()  相当于把new Inner08()当作outer08的成员?????????
        Outer08.Inner08 inner08=outer08.new Inner08();//
        inner08.say();
        //                      用外部类的对象newl一个内部类的实例然后返回给他
        //把Outer08去掉就是一个正常对象的实例化,~!!!!~~



        //方法2:在外部类中,编写一个方法,可以返回Inner08的对象;
        //
       /* outer08.getClass()
        inner081Instance.say();*/

    }
}
class Outer08{//外部类。

    private int n1=10;
    private String name="kk";

    class Inner08{//成员内部类!:在成员位置上
        public void say(){//可以直接访问外部类所有成员(包含私有)!
            System.out.println("n1="+n1+" "+"name="+name);
        }

        public Inner08 getInner08Instance(){//方法2.在外部类中,编写一个方法,可以返回Inner08的实例对象;
            return  new Inner08();//返回Inner08的对象,所以就可以调用它的方法;
        }

    }
     //写方法:用于外部类访问内部类
    public void show(){//因为外部类不能直接访问内部类的成员!!!

        // 所以定义外部类方法show;使外部类可以访问内部类的成员!!!!!
        Inner08 inner08=new Inner08();//创建成员内部类的对象;
        inner08.say();//调用成员内部类的方法say;
    }
}

5.静态内部类:

1.静态内部类简介:
静态内部类:static Class
1.a:使用static修饰,b:在外部类的成员位置
2.!!静态内部类可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员;
3.可以添加任何访问修饰符(因为在成员位置上)
4.静态内部类的作用域:整个类体(同其它成员一样)
5.访问方式:a:静态内部类---访问--->外部类(比如:静态属性)
           访问方式:直接访问所有!静态!成员;(静态只能访问静态)
           b:外部类----访问---->静态内部类;
            访问方式:创建方法-->创建对象--->调用方法

6.外部其它类  使用静态内部类:
  方式1:Outer10.Inner inner10=new Outer10.Inner10();
 7.如果外部类和静态内部类的成员重名时,静态内部类访问时:默认遵循就近原则。
  如果想要访问外部类的成员:(外部类名.成员)去访问
  //因为:静态内部类是静态的,静态的只能访问静态的,所以不用加this~!!
2.演示:
public class StaticClass {
    public static void main(String[] args) {
        Outer10 outer10=new Outer10();
        outer10.m1();

        //.外部其它类  使用静态内部类:方式1:
        //因为静态内部类是可以通过类名直接访问的!
        Outer10.Inner10 inner10=new Outer10.Inner10();
        inner10.say();

        //方式2:编写一个方法:可以返回静态内部类的实例
        Outer10.Inner10 inner101=outer10.getInner10();//使用Outer10.Inner10 inner101接收
        System.out.println("=============");
        inner101.say();

        //方式3
        Outer10.Inner10 inner=Outer10.getInner_();
        System.out.println("*************");
        inner.say();
    }
}

class Outer10{//外部类
    private int n1=10;
    private static String name="张三";


    static class Inner10{//静态内部类

       // private String name="kk";//重名就近原则
        public void say(){
            System.out.println(name);//静态内部类可以直接访问外部类的所有静态成员,
            //System.out.println(n1);//但不能直接访问非静态成员

            //System.out.println("外部类的name="+Outer10.name);// 如果想要访问外部类的成员:(外部类名.成员)去访问
        }

    }

    public void m1(){
        Inner10 inner10=new Inner10();
        inner10.say();
    }

    //方式2:编写一个方法:可以返回静态内部类的实例
    public Inner10 getInner10(){
        return  new Inner10();
    }

    //方式3:编写一个静态方法:科研返回静态内部类的实例
    public static Inner10  getInner_(){
        return new Inner10();
    }
    //
}

3.枚举

1.枚举简介:

枚举的引出:
1.枚举是一个类。
2.枚举类:即把具体的对象一个一个的列举出来的类!!!
3.枚举类中所有的成员都是public static final
    
    
    枚举基本介绍:
1.枚举是一组常量的集合;
2.可以理解为:枚举属于一种特殊的类,里面包含一组有限的特定对象。

3.枚举的两种实现方式:
A:自定义类实现枚举:
 1.构造器私有化;(构造器私有化后在外面就不能new对象了)。
 2.去掉set方法(防止set方法修改属性等,且因为枚举对象值通常为只读,可以有get)
 3.对外暴露对象:在该类(Seasons)内部创建固定的对象(有几个就创建几个),final+static修饰对象
 4.优化:加入fianl修饰符对象(属性):final+static修饰不会导致类的加载(final你不可能去修改)
 注意:a:枚举对象名通常要全部大写/
      b:加入fianl+static共同修饰符对象(属性)/
      c:枚举对象根据需求可以有多个对象
      d:枚举类中的成员都是static类的,使用可以直接使用类名访问!!!!!!!!!!
B:使用enum关键字实现枚举
演示:

2.演示A:自定义类实现枚举::

public class Enum02 {
    public static void main(String[] args) { //main方法·
        //new Seasons()//不能再new对象;
        //set:也不能修改
        System.out.println(Seasons.Spring);//静态可以直接:类名.对象;可以使用toString打印出来!!
        System.out.println(Seasons.Summer);
        System.out.println(Seasons.Autumn);
        System.out.println(Seasons.Winter);
    }
}

/*
演示自定义枚举的实现:
1.构造器私有化:(构造器私有化后在外面就不能new对象了)。
2.去掉set方法(防止set方法修改属性等)
3.在该类(Seasons)内部创建固定的对象(有几个就创建几个)
4.优化:加入fianl修饰符对象:final+static修饰不会导致类的加载(final你不可能去修改)
 */
class Seasons{
    private String name;
    private  String desc;//描述

    //定义四个固定对象:就不能增加或减少对象了
    public static final Seasons Spring=new Seasons("春天","温暖");
    public static Seasons Winter=new Seasons("冬天","寒冷");
    public static Seasons Autumn=new Seasons("秋天","凉爽");
    public static Seasons Summer=new Seasons("夏天","炎热");



    private Seasons(String name, String desc) {//构造器私有化
        //构造器私有化后在外面就不能new对象了

        this.name = name;
        this.desc = desc;
    }
    //get,set
    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

    @Override
    public String toString() {
        return "Seasons{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

3.演示实现枚举的第二种方式:使用enum关键字实现枚举::

//实现枚举的第二种方式:使用enum关键字实现枚举:
/*步骤:
1.使用关键字enum代替class
2.构造器私有化
3.无set
4.public static Seasons Spring=new Seasons("春天","温暖");==改为--->:Spring("春天","温暖"):对象名(实参列表):
实参列表会根据实参和相应构造器相关联;

 */

/*
使用eum关键字实现枚举的注意事项/细节
1.如果有多个对象,使用”,“隔开,最后一个带分号;!!
2.如果使用enum来实现枚举,要求将定义的常量对象,写在类的最前面;
3.当我们使用enum关键字开发一个枚举类时,默认会继承Enum类,而且是一个final类
4.如果我们使用的是无参构造器,创建对象时,则可以省略();eg:WHAT()==WHAT;
 */

//演示:
//enum枚举类1

public class Enum03 {
    public static void main(String[] args) {//main
        System.out.println(Season2.SPRING);//==public static Seasons Spring=new Seasons("春天","温暖")
        System.out.println(Season2.SUMMER);
        System.out.println(Season2.AUTUMN);
        System.out.println(Season2.WINTER);

    }
}
enum Season2{
    SPRING("春天","温暖"),SUMMER("夏天","炎热"),AUTUMN("秋天","凉爽"),
    WINTER("冬天","寒冷"),/*WHAT()*/;
    //解读:对象名(实参列表):实参列表和构造器相关联;
    private String name;
    private  String desc;//描述

    Season2() {//无参构造器
    }

    private Season2(String name, String desc) {//构造器
        this.name = name;
        this.desc = desc;
    }
    //get,set
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
    @Override
    public String toString() {//toSring方法用来输出信息
        return "Seasons{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }

4.枚举使用细节:

//枚举使用细节:
/*
1.使用enum关键子后,就不可以有继承(extends):---(因为它已经有一个隐式的继承:Enum,java单继承机制)
2.但是可以实现接口;下面的是演示:!!!

 */
public class EnumDetails {
    public static void main(String[] args) {
       /* IPlaying iPlaying=new Music();//传统方法
        iPlaying.playing();*/

        Music.CLASSMUSIC.playing();
        //Music.CLASSMUSIC:表示:枚举类的对象!!!!!!!!
    }
}
class A{

}
interface IPlaying{//接口
    void playing();


}
enum Music implements IPlaying{
    CLASSMUSIC();//创建枚举对象:是静态的--->:所以可以直接调用!!!!
    public void playing(){//实现接口的方法==重写!!!
        System.out.println("播放:只因你太美~~~~");
    }
}

4.异常:(!!!)

1.异常简介:

引入:eg:当出现异常(错误),程序就会退出,崩溃了,下面的代码就不会执行,程序就会报异常;
但如果出现了一个不是致命的错误就退出(崩溃),那么健壮性太差。---->:这时候引出了:异常处理机制来解决。
1.出现异常可以使用:try-catch”异常处理机制“来解决
步骤:将该代码块选中-->:使用快捷键:ctrl+alt+t->选中 try-catch
2.如果进行了异常处理。那么即使出现了异常,程序也可以继续执行

2.演示:

*public class Exception01 {
    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 0;z
        try {
            int res = num1 / num2;
        } catch (Exception03 e) {
           e.printStackTrace();
            //System.out.println(e.getMessage());//2.也可以直接把使用这个:就不会报错了,且会将异常信息显示出来
        }
        //0不可以做除数,所以会报错,为了增强健壮性,可以使用try-catch”异常处理机制“来解决;

        System.out.println("程序正常执行........");//1.加上异常处理后遇到 int res = num1 / num2;不会停止,仍会报错但,一直会执行到最后输出这句话!


    }*/

//}

3.异常细节

异常:指的是程序执行过程中发生的不正常情况,但语法错误和逻辑错误不算;

执行过程中所发生的异常事件可以分为两大类:
1.Error(错误):是致命严重错误,程序会崩溃,无法通过异常处理机制来实现!!!;

重点:
2.Exception:因编译错误或欧瑞的外在问题导致的一般性问题!!!
分为两大类:
a:运行时异常[程序运行阶段发生的异常];编译器检测不出来,往往是逻辑错误,eg:num/0:
b:编译时异常[编程阶段,编译器检查出的异常]

注意:1.运行时异常可以不做处理;(因为它很普遍,若都处理会会影响代码可读性,运行效率)
2.而编译异常必须处理!!!!!!
3.异常体系图:体现了继承和实现功能。

运行时异常:

*
一:5大运行时异常:
1.空指针异常:当应用程序试图在需要对象的地方使用null时会抛出异常;
2.算数异常:num/03.数组下标越界异常(为负数或超出数组长度)
4.类强制转换异常:当试图将对象强制转换为不是实例的子类时,抛出异常。
5.数字格式不正确异常:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出异常
 */
public class Exception3 {
    public static void main(String[] args) {
        //1.空指针异常
        //String name="kk";
        String name=null;
        //System.out.println(name.length());//需要name,但是name为null,所以异常;
        //2.算数异常:num/0;

        //3.数组下标越界异常(为负数或超出数组长度)
        int []arr={1,2,3};
       /* for(int i=0;i<=arr.length;i++){//arr数组越界
            System.out.println(arr[i]);
        }*/

        //4.类强制转换异常:当试图将对象强制转换为不是实例的子类时,抛出异常。
        /*A a=new B();//向上转型ok
        B b1=(B) a;//向下转型ok
        C c=(C) a;*///C类域B类无继承关系


        //5.数字格式不正确异常:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出异常
        //eg:将String转为int
        String name1="kkkk";
        int num=Integer.parseInt(name);
        System.out.println(num);


    }
}
class A{}
class B extends A{}
class C extends A{}

4.异常处理机制简介:

异常处理机制:!!!!!

如果程序员认为程序可能会有异常时(或抛出异常时):
异常处理的方式(二选一!!):
(1.):try-catch-finally处理机制:
try{
    (可能异常的代码)
}catch(Exception e){
   (捕获到的异常)--->                //当异常发生时,系统将异常封装成Exception的对象e,然后传给catch;
                                  //得到异常对象后,程序员自己处理
                                  //如果try代码块没有发生异常,则catch代码块不执行!!
}finally{   --->                      //不管try代码块是否有异常发生,都会执行finally代码块;
                                   //所以通常将释放资源的代码放到finally中;
}
finally可写可不写!
(2.throws处理机制:
一直往上扔:扔到上一级,之后上一级要么try-catch,要么继续throws到上一级。...若一直没有try,则一直到扔到最顶级的处理者JVM
JVM会a:会输出异常信息,b:然后退出程序


注意:1.try-catch-finall处理机制和throw处理机制只能二选一!!!
2.如果程序员没有显示处理异常,默认使用throws处理异常

1.try-catch方式处理异常说明

package Exception;
/*
try-catch方式处理异常说明:

1.)try块用于包含可能出错的代码,try:尝试执行。catch块用于!捕获!!处理!try块中发生的异常。
可以根据需要在程序中有多个try...catch块;

2.)基本语法:
try{
    可疑代码
}catch(异常:Exception e){
   对异常进行处理 1.e.printStackTrace();
            //2.System.out.println(e.getMessage());
}finally{可不写

}

3.):try-catch细节:+演示:
1.如果发生异常,则异常后面的代码不会执行,直接进入到catch块;
2.如果异常没有发生,则顺序执行try代码块,不会进入catch(因为没异常,不用捕获)
3.如果希望希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等),则使用finally(总会执行!)
4.如果try代码块有多个异常,我们可以使用多个catch语句,来分别捕获不同的异常(进行不同的业务处理),相应的处理。(但前提得先知道异常的类型!)
注意:但要求父类异常在后,子类异常在前;!!!
Exception包含所以的异常-->:所以Exception是父类
其它异常是子类

(都是Exception的子类,如果把E写在前面,就只捕获1个)
eg:


5.try-finally

 */
//演示:
public class TryCatch {
    public static void main(String[] args) {
       /* try {
            String str="kk";//a:
            int a=Integer.parseInt(str);////b认为这部分可能出现异常
            System.out.println("数字:"+a);//c
        } catch (NumberFormatException e) {//d
            System.out.println("异常信息:"+e.getMessage());//e
            throw new RuntimeException(e);//f
        } finally {
            System.out.println("finally代码块都会执行....");
        }
        //解读:因为b出现异常,所以b(异常)之后的代码c不会执行,直接会进入catch块;


        */

        //演示第4点b部分:一:使用一个catch时:


        try {
            Person person=new Person();
            //person=null;//空指针//a.
            System.out.println(person.getName());//空指针异常b.
            int n1=10;
            int n2=0;
            int res=n1/n2;//算数异常c.
        } catch (Exception e) {
            System.out.println(e.getMessage());//(1.)当使用一个catch时:
            // 只会输出“空指针异常”,因为执行到异常后,下面的代码就不会执行,而是直接到catch代码块中,然后输出异常信息。
            //2.)但如果没有a那句话,b会正常执行,然后直到遇到c异常,则跳到catch代码块中输出异常信息。
        } finally {
        }
        //上述代码有两个异常(或者有多个),这时我们可以使用多个catch来捕获异常;




        //演示第4点b部分:一:使用多个catch时
        try {
            Person person=new Person();
            person=null;
            System.out.println(person.getName());//空指针异常1  //b.
            int n1=10;
            int n2=0;
            int res=n1/n2;//算数异常2    //c.
        } catch (NullPointerException e) {//第一个catch捕获:空指针异常
            System.out.println("空指针异常:="+e.getMessage());

        } catch(ArithmeticException e){//第二个catch捕获算数异常
            System.out.println("算数异常:="+e.getMessage());
        }
        catch(Exception e){
            System.out.println(e.getMessage());
        }
        finally {

        }
    }
}

//演示第4点a部分:
class Person{
    private String name="kunkun";
    public String getName(){
        return name;
    }
}

2.try-catch补充:

细节5.1):也可以进行 try-finally配合使用,这种用法相当于没有捕获异常(因为没有catch);
因此执行完finally后程序会直接崩掉/退出。
(2).应用场景:就是执行一段代码,不管是否发生异常,都必须执行某个业务逻辑(即finally块中的·)

演示
 */
public class TryCatch2 {
    public static void main(String[] args) {


        try {
            int n1=10;
            int n2=0;//会出现异常:算数异常
            System.out.println(n1/n2);    //a
        } finally {
            System.out.println("执行finally.....");    //b
        }
        System.out.println("程序继续执行...");      //c
//解读:有异常,但是因为没有catch捕获异常,所以在a处发生异常后会直接到finally执行b,然后退出程序(崩掉)
        //注意:1.不会执行c语句!!!!!!!!!
        //最后输出b,是JVM输出的:因为没有做任何处理的化,默认是throws处理机制,一直到JVM,
        // JVM会a:输出错误信息,然后b退出程序(崩掉),所以没有机会执行c就会崩掉;
    }
}

3.throws异常处理机制

//异常处理机制二:throws异常处理机制:
//throws入门

/*
1.基本介绍:
1.)如果一个方法可能有异常但不确定如何处理这种异常,则此方法应显示的声明(明确的抛出:即不处理)抛出异常
表示:不对异常进行处理,而由该方法的调用者负责处理。


2.)在该方法中用throws语句可以声明抛出异常的列表,
throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类

直接抛给父类:Exception!!!!!!!!!(一般使用这种!!!!!1)
 */

import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class Throws {
    public static void main(String[] args) {

    }
    public void f1(){
        try {//1.使用try-catch
            FileInputStream fis=new FileInputStream("\"d://aa.txt\"");//异常!!!
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /*public void f2() throws FileNotFoundException{//第二种处理机制a::throws
        // 使用throws抛出异常:即f2自己不处理,让调用f2方法的调用者处理
        FileInputStream fis=new FileInputStream("\"d://aa.txt\"");
    }

     */
    //直接抛给父类:Exception!!!!!!!!!(一般使用这种!!!!!1)
   /* public void f2() throws Exception{//第二种处理机制b::throws
        //throws后面的异常类型可以是方法中产生的异常类型(即明确的如FileNotFoundException),也可以是它的父类Exception
        FileInputStream fis=new FileInputStream("\"d://aa.txt\"");
    }
    */

    //c:throws关键字后面也可以是   异常列表,即可以抛出多个异常;
    public void f2() throws FileNotFoundException,NullPointerException{//第二种处理机制b::throws
        FileInputStream fis=new FileInputStream("\"d://aa.txt\"");
    }
}

4.throws使用细节:

throws异常处理机制细节:

1.编译异常必须!显示!处理(运行时异常可以不用处理);
egFileInputStream

2.a:对于运行时异常,程序如果没有显示处理,默认是使用throws处理(即自己可以不用处理)
eg:public void f2()/默认:throws Exception/ {
     int n=10/0;
}
b:而编译运行异常没有默认处理,必须显示处理(即使用两种中的一种)!!!!!!!!!!!!!!
3. 子类重写父类方法时,对抛出的异常的规定是:子类重写方法所抛出的异常必须和父类一样,或者为父类异常的子类!
        (即子类不能缩小父类的范围,返会类型也是)。
4.catchthrows是两种处理机制:只能选择一种;