✿动手实验一:下列语句哪一个将引起编译错误?为什么?哪一个会引起运行时错误?为什么?
m=d;
d=m;
d=(Dog)m;
d=c;
c=(Cat)m;
先进行自我判断,得出结论后,运行TestCast.java实例代码,看看你的判断是否正确:
其中m是父类对象,d和c是子类对象,java中基类对象不能当做子类对象使用,需要用强制转换来实现,具体语法为:子类对象变量=(子类名)基类对象名;
错误的代码是d=m; d=c;
错误原因:类型不匹配:不能从 Mammal 转换为 Dog。
✿动手实验二:运行以下测试代码
1.上边的程序运行结果是什么?
Parent.printValue(),myValue=100
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=200
Child.printValue(),myValue=201
2.你如何解释会得到这样的输出?
上面代码中父类和子类有相同名字的方法,并且把子类的对象赋值给了父类的对象,这是父类的parent其实是子类的类型,所以value++是加在了父类中而调用的函数是子类的,所以输出的是子类的value为200,语句((Child)parent).myValue++;将parent对象强制转化成Child,所以指向的是Child类中的变量,进行自加运算之后输出。
3.计算机是不会出错的,之所以得到这样的运行结果也是有原因的,那么从这些运行结果中,你能总结出Java的哪些语法特性?请务必动脑总结,然后修改或编写一些代码进行测试,验证自己的想法,最后再看后面的PPT给出的结论。
(1)当子类与父类拥有同名的方法,并且让一个父类变量引用一个子类对象时,到底调用哪个方法,由对象自己的“真实”类型所决定,这就是说:对象是子类型的,它就调用子类型的方法,是父类型的,它就调用父类型的方法。
(2)如果子类与父类有相同的字段,则子类中的字段会代替或隐藏父类的字段,子类方法中访问的是子类中的字段(而不是父类中的字段)。如果子类方法确实想访问父类中被隐藏的同名字段,可以用super关键字来访问它。
(3)如果子类被当作父类使用,则通过子类访问的字段是父类的。
(4)这实际上就是面向对象“多态”的具体表现。
✿动手实验三:请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识。
✿动手动脑四:当有多个嵌套的try…catch…finally时,要特别注意finally的执行时机。
请先阅读 EmbedFinally.java示例,再运行它,观察其输出并进行总结。
特别注意:
当有多层嵌套的finally时,异常在不同的层次抛出,在不同的位置抛出,可能会导致不同的finally语句块执行顺序。
1)、只有与 finally 相对应的 try 语句块得到执行的情况下,finally 语句块才可能会执行。
2)、在 try 语句块中执行了 System.exit (0) 语句,终止了 Java 虚拟机的运行时。
3)、当一个线程在执行 try 语句块或者 catch 语句块时被打断(interrupted)或者被终止(killed),与其相对应的 finally 语句块可能不会执行。
4)、更极端的情况,就是在线程运行 try 语句块或者 catch 语句块时,突然死机或者断电,finally 语句块肯定不会执行了。
5)、不管 try 语句块正常结束还是异常结束,finally 语句块是保证要执行的。如果 try 语句块正常结束,那么在 try 语句块中的语句都执行完之后,再执行 finally 语句块。如果 try 中有控制转移语句(return、break、continue)finally 语句块在 try 或catch语句块中的 return 语句之前执行。
✿动手动脑五:辨析:finally语句块一定会执行吗?
请通过 SystemExitAndFinally.java示例程序回答上述问题
同上述情况2)
需要验证的课堂例子:
1. 参看实例: TestInstanceof.java
2.阅读以下代码(CatchWho.java)
3. 写出CatchWho2.java程序运行的结果
当程序中出现异常时,JVM会依据方法调用顺序依次查找有关的错误处理程序。
可使用printStackTrace 和 getMessage方法了解异常发生的情况:printStackTrace:打印方法调用堆栈。每个Throwable类的对象都有一个getMessage方法,它返回一个字串,这个字串是在Exception构造函数中传入的,通常让这一字串包含特定异常的相关信息。
4.ThrowMultiExceptionsDemo.java示例展示了以下相关特性。
一个方法可以声明抛出多个异常 int g(float h) throws OneException,TwoException{ …… },值得注意的特殊之处是:当一个方法声明抛出多个异常是,在此方法体中只要catch其中一个异常,程序就能顺利运行。
展示了Java“一个子类的throws子句抛出的异常,不能是其基类同名方法抛出的异常对象的父类”的语法特性。
//如果test方法声明抛出了比父类方法更大的异常,比如Exception,则代码将无法编译…
6.ExceptionLinkInRealWorld.java示例展示了典型的异常处理代码模板。