第08章 内部类与异常
- 格式:pptx
- 大小:165.15 KB
- 文档页数:19
异常和异常类的概念
程序编译通过后,并不意味着运行时就能得到正确的结果。
很可能由于编程时考虑不周或运行时遇到一些特殊情况(如:除法运算时除数为0,访问数组时下标越界,要打开的文件不存在等等),结果出现中断程序正常运行的情况。
Java把这类导致程序中断运行的错误称为异常(英文:exception,意思:例外),Java有一系列机制来捕获、处理异常。
Java有一个著名的观点:“万物皆对象”,因此,也把异常当作对象来处理(异常是异常类的对象),当发生异常时创建异常对象。
常见的异常类都位于ng包中,例如:
ArithmeticException:除数为0时的算术异常
NullPointerException:没有给对象分配内存空间,而又去访问对象的空指针异常
FileNotFoundException:找不到文件的异常
ArrayIndexOutOfBoundsException:数组元素下标越界异常
NegativeArraySizeException:数组长度为负数异常
NumberFormatException:数据格式不正确异常ClassNotFoundException:找不到相应类的异常。
1内部类1.1 内部类的概述将类定义在另一个类的内部则成为内部类。
其实就是类定义的位置发生了变化。
在一个类中,定义在类中的叫成员变量,定义在函数中的叫成员函数,那么根据类定义的位置也可以分为成员内部类和局部内部类。
备注:内部类生产的class文件为“外部类$内部类”,为了标明该内部类是属于具体哪个外部类的。
1.2 成员内部类的访问方式1.内部类可以直接访问外部类的成员属性。
(孙悟空相当于内部类飞到牛魔王的肚子里面去)。
2.外部类需要访问内部类的成员属性时需要创建内部类的对象。
1.在外部类的成员函数中创建内部类的对象,通过内部类对象对象直接访问内部类的成员。
2.在其他类中直接创建内部类的对象。
Outer.Inner inner = new Outer().new Inner();外部类访问内部类的属性编译异常分析:外部类需要访问内部类的属性时,需要创建内部类的对象访问。
有A类和B类,当A类想要直接访问B类中的成员,而B类又需要建立A类的对象来A 类中的成员。
这时,就将A类定义成B类的内部类。
比喻:孙悟空和铁扇公主。
孙悟空到了公主肚子中,就成了内部类(其实是持有外部类的对象引用)。
疑问:什么时候使用内部类呢?当我们分析事物时,发现事物的内部还有具体的事物,这时则应该定义内部类了。
比如人体是一个类,人体有心脏,心脏的功能在直接访问人体的其他内容。
这时就将心脏定义在人体类中,作为内部类存在。
内部类的优势:成员内部类作为外部类的成员,那么可以访问外部类的任意成员。
1.3 成员内部类访问细节私有的成员内部类不能在其他类中直接创建内部类对象来访问。
如果内部类中包含有静态成员,那么java规定内部类必须声明为静态的访问静态内部类的形式:Outer.Inner in = new Outer.Inner();总结:成员内部类(成员属性、成员方法)特点:1.私有的成员内部类特点:不能在其他类中直接创建内部类对象来访问2.静态的成员内部类特点:如果内部类中包含有静态成员,那么java规定内部类必须声明为静的访问静态内部类的形式:Outer.Inner in = new Outer.Inner();疑问:目前打印的num是20,如果想打印10的话,应该怎么做?解答:这时候其实在show方法中已经存在了两个this对象,一个是外部类对象,一个是内部类对象,所以要在this前面加上类名标明对应的this。
第8章高级特性:内部类和异常一、本章知识点●知识点1:内部类成员内部类、静态内部类、匿名内部类、局部内部类外部类又叫Top class顶级类,通常必须是public的内部类的分类:成员内部类、静态内部类、匿名内部类、局部内部类包含在外部类中的不带static的内部类,叫成员内部类(跟随外部类实例对象)包含在外部类中static修饰的内部类,叫静态内部类(类似顶级类,仅仅是可见性有区别) 内部类的特点:内部类可以很好的实现隐藏,可以使用protected修饰、private修饰符;内部类可以直接访问外部类的所有成员,包括私有的成员;外部类不能直接访问内部类的成员,必须首先要建立内部类的对象才可访问。
重点:怎样在成员内部类(实例)方法中访问外部类(实例)对象?Outter.this.属性(方法)怎样在测试类中创建内部成员类对象?Inner inner = outer.new Inner();//需要导包,内部类在外部不可见匿名内部类: 当某个方法的参数是抽象类或者接口时,在调用处直接new这个抽象类或接口,使用局部重写方法实现的方式,称为匿名内部类,这类语法在Java/Android 中极其常见!(形参是普通父类,直接new一个匿名内部类局部重写普通父类的某个方法这种语法也存在,但不太多见)1.1.1【案例1:演示、讲解】成员内部类/*外部类中创建成员内部类测试成员内部类的访问*/public class OuterClass {private String name;private int id;//创建外部类方法public void show(){System.out.println("外部类对象的姓名:"+name+" 学号:"+id);}/*** 创建成员内部类*内部类中不能声明静态的方法和属性(静态常量除外)* 1.测试创建内部类对象* 2.测试内部类如何访问外部类的属性*/public class MemberInnerClass{private String name;private int id;/*** 创建成员内部类方法*/public void Innershow(){//2 测试外部类的属性System.out.println("外部类对象的姓名:"++" 学号:"+OuterClass.this.id);//访问外部类的方法OuterClass.this.show();//show(); //成员内部类可以直接访问外部类的属性和方法//外部类不能直接访问内部类的属性和方法,如果调用可以先创建对象System.out.println("成员内部类对象的姓名:"+name+" 学号:"+id);}}}1.1.2【案例2: 练习、讲解】静态内部类//测试静态内部类和外部类在上面案例中加入静态内部类public static class StaCalss{private String name="zhangsan";private int id=10;public void staShow(){System.out.println("静态内部类对象的姓名:"+name+" 学号:"+id);//静态内部类不能访问外部类非静态的成员//外部类访问静态内部类非静态的成员通过对象.属性(方法)System.out.println(OuterClass.score);}}//测试类里加入OuterClass.StaCalss osc=new OuterClass.StaCalss();osc.staShow();1.1.3【案例3: 练习、讲解】局部内部类//在第一个例题中加入方法方法测试类中oc.showInner();public void showInner(){final int score1=5;System.out.println("外部类对象的姓名:"+name+" 学号:"+id);class PInner{private String name="zhngsi";private int id;public void showPInner(){System.out.println(name);//局部内部类只能访问其方法中声明的常量System.out.println(score1);//访问外部类的属性System.out.println("外部类对象的姓名:" + + " 学号:" + OuterClass.this.id);}}1.1.3【案例4:、讲解】匿名内部类//测试匿名内部类public abstract class Student {public abstract void sayHi();} /*** 形参是抽象父类* @param stu*/public void testStudent(Student stu){stu.sayHi();}/*** 形参是接口* @param intf*/public void testIntf(Intf intf){intf.on();intf.off();}/*** 形参是系统API某个接口* @param com*/public void testComparator(Comparator<String> com){}/**** @param args*/public static void main(String[] args) {TestAInnerType test = new TestAInnerType();test.testIntf(new Intf(){@Overridepublic void on() {System.out.println("test on");}@Overridepublic void off() {System.out.println("test off");}});new TestAInnerType().testComparator(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {return pareTo(o1);}});TestAInnerType test1 = new TestAInnerType();test1.testStudent(new Student(){@Overridepublic void sayHi() {System.out.println("局部重写sayHello");}});String[] ary = new String[]{"abb","aab","abc"};System.out.println("默认升序");Arrays.sort(ary);for(String s: ary){System.out.println(s);}System.out.println("降序(匿名内部类实现)");Arrays. Sort(ary, new Comparator<String>() { //此处new出来的是接口的实//现类,是子类@Overridepublic int compare(String o1, String o2) {return pareTo(o1);}});for(String s: ary){System.out.println(s);} }}/*** 测试接口* @author Ava**/interface Intf{public void on();public void off();}●知识点2:自动拆箱和封箱引用类型和基本数据类型之间的转换,称为装箱拆箱常用包装类: Integer,Double,Character,Boolean,FloatLong装箱操作: int ->Interger将基本类型自动转换成相对应的包装类拆箱操作: Integer-> int将包装类转换成基本类型总结:字符串转基本数据类型:包装类.parseXXX(String str)方法基本数据类型转字符串:String.valueOf(基本数据类型)方法2.1.1【案例5:演示、讲解】自动拆箱和封箱//将引用类型转赋值给基本类型(Integer int),如何将字符串通过包装类转换成基本数据类型Integer it=new Integer(124);Int a=it; //将引用类型赋值给基本数据类型(自动拆箱)It=123; // 将基本数据类型赋值给引用类型(自动装箱)Sout(it.toString())Strings1=new String(“123”);Int i=Integer.parseInt(s1); //将String字符串转换成基本数据类型前提是字符串中//必须是基本数据类型的数据//如何将基本型转换成String字符串Inti=10;String s=”“;s=String.valueOf(i); //此方法返回int参数的字符串形式查APIs=i+””; //通过连接符将数字和字符串连接Integer is=i; //先将基本类型封装成引用类型s=is.toString(); //调用toString()方法返回字符串//从键盘获得一个小数,先转换成字符串,再转换成小数输出●知识点3:String、StringBuffer、StringBuilder//String类的两种创建方式特点String对象一旦创建就不能改变,如果需要大量的字符串操作,使用StringBuffer/StringBuilder;StringBuffer:线程安全的字符串序列;类似于String字符串缓冲区;通过调用某些方法可以改变该序列的长度和内容;每个字符串缓冲区都有一定的容量,只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组;如果内部缓冲区溢出,则此容量自动增大。