//101-finally的使用&102-finally的使用场景
/*
需求:有一些特定的代码,无论异常是否发生,都需要执行,
因为异常会引发程序的跳转,导致有些语句执行不到,无法满足这个需求。
异常捕获处理时,java提供了解决方案。
try catch finally.
finally:就是解决这个问题的。这个代码块中存放的代码都是一定会被执行的。 应用场景:
定义一个功能,往数据库中添加数据。
void add(Data data)throws NoAddException
{
//1,连接数据库。
try{
//2,添加数据。//很有可能在添加数据时,发生了异常情况,很可能发生了异常情况:throw new SQLException();程序就会跳转就执行不到断开连接,
//而断开连接必须要执行,因为不执行断开功能,
//那么连接资源会浪费。无论是否发生问题都需要执行断开连接的动作,从而释放资源。
}catch(sqlException e)
{
//解决数据库的问题。
//同时将问题告诉调用者。
//throw new NotAddException();
}
finally
{
//3,断开连接。
} //总结:finally到底什么时候用,
只要程序中使用到了具体的资源(数据库,IO资源,网络连接(socket)等)
需要释放,都必须定义在finally中。你这定义程序时,只要问题发生与否,
指定程序都需要执行时,就定义在finally里面。
}
*/
class NoShowException extends Exception
{
NoShowException()
{
super();
}
NoShowException(String message)
{
super(message);
}
} class Demo
{
void show(int num)throws NoShowException
{
if(num<0)
throw new NoShowException(num+",数值是非法的");
System.out.println("show run...."+num);
}
}
class ExceptionDemo10
{
public static void main(String[] args)
{
/*
Demo d = new Demo();
//因为调用到了声明异常的show方法,所以调用者要给出处理的方式,
//要么继续声明,要么捕获。
try
{
d.show(-5); }
catch (NoShowException ex)
{
System.out.println(ex.toString());//打印的是异常名称+异常信息。
//如果异常发生,处理完毕后,希望功能结束。
return; //注意:有一种情况发生,finally也不执行,
// System.exit(0);//退出jvm.
}
finally
{
System.out.println("hello");
}
System.out.println("over");
*/
Test t = new Test();
int num = t.show(-4);
System.out.println("num="+num);
}
} class Test
{
int show(int num)
{
try
{
if(num<0)
throw new RuntimeException();
return 4;
}
catch (Exception e)
{
System.out.println(e.toString());
return 200;
}
finally
{
System.out.println("finally run");
return 100;
}
}
}
//103-trycatchfinally的组合方式。
/*
try catch finally几种组合方式; 1,
try catch: 对代码进行异常检测,并对检测的异常传递给catch处理。
异常捕获处理。 void show()//不用throws
{
try{
throw new Exception();
}catch(Exception e)
{ }
}
2
try finally: 对代码进行异常检测,检测到异常后因为没有catch所以一样会被默认jvm抛出。
异常是没有捕获处理的。但是功能所开启的资源需要进行关闭,所以有finally.
关闭资源。 void show()//需要throws
{
try{
throw new Exception();
}finally
{ }
} 3,
try catch finally
检测异常,并传递给catch处理,并定于资源释放, 4,try catch1 catch2 catch3....
*/ class
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
//104-异常在覆盖中的细节。
/*
异常在继承或者实现中的使用细节:
1,子类在覆盖父类方法时,如果父类的方法声明异常,
子类只能声明父类异常或者该异常的子类,或者不声明。
2,当父类方法声明多个异常时,子类覆盖时只能声明多个异常的子集。
3,当被覆盖的方法没有异常声明时,子类覆盖时是无法声明异常的。
举例:父类存在这种情况,接口也有这种情况。
问题:接口中没有声明异常,而实现的子类覆盖方法时却发生了异常,怎么办?
无法进行throws声明,只能进行catch的捕获。万一问题处理不了呢?可以在
catch中继续throw抛出,但是只能将异常转换成RuntimeException抛出。 Interface Inter
{
public void show();
}
class Demo implements Inter
{
public void show()//不能进行throws声明。把编译时异常转换成运行时异常。
{
try{
throw new Exception();
}catch(Exception e)
{
code..//自己的处理方式。
//不能处理时,转换。
throw new RuntimeException("");//告知调用者问题所在。
}
}
}
Exception
|-AException
|-AAException
|-BException */
class AException extends Exception
{
}
class BExcepiton extends Exception
{
}
class AAExcepiton extends AException
{
} class Fu
{
void show()throws AException
{ }
} class Tool
{
void method(Fu f)
{
try
{
f.show();
}
catch (AException ex)//AException ex = new AAException();
{
} }
}
Tool t = new Tool();
//t.method(new Fu());
t.method(new Zi()); class Zi extends Fu
{
void show()throws AAException
{ }
} class ExceptionDemo12
{
public static void main(String[] args)
{
Zi z = new Zi();
try
{
z.show();
}
catch (AException e)
{
}
}
}
package mypack;//包名中的所有字母都小写。
/*
对于多个类为了便于管理(类的同名情况),所以Java提供了解决方案。
包机制:落实到操作系统上,就是文件夹。对Java的文件进行分文件管理。 包的定义:使用关键字package。 包的作用:
1,对类文件进行管理。
2,给类文件提供了名称空间。 对带有package定义的java文件进行指定类文件位置的编译方式。
javac -d 目录 源文件 如果目录选择的不是当前目录,想要访问包中类。
通过设置classpath. set classpath=包所在的父目录 =====================================================
包与包之间的访问:
PackageDemo1.java:24: 错误: 找不到符号
DemoA d = new DemoA();
^
符号: 类 DemoA
位置: 类 PackageDemo1
PackageDemo1.java:24: 错误: 找不到符号
DemoA d = new DemoA();
^
符号: 类 DemoA
位置: 类 PackageDemo1 原因是:类名写错,有了包的类,类名:包名.类名。这才是类的全名称。
解决:使用DemoA,必须写packa.DemoA. ================================================================
PackageDemo1.java:41: 错误: 程序包packa不存在
packa.DemoA d = new packa.DemoA();
^
PackageDemo1.java:41: 错误: 程序包packa不存在
packa.DemoA d = new packa.DemoA();
^
2 个错误 原因:packa这个包没有找到,在当前目录下。
解决:应该告诉jvm这个程序包的位置. set classpath. ====================================================================
PackageDemo1.java:41: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行访问
packa.DemoA d = new packa.DemoA();
^
PackageDemo1.java:41: 错误: DemoA在packa中不是公共的; 无法从外部程序包中对其进行访问
packa.DemoA d = new packa.DemoA();
^
2 个错误 原因:DemoA这个类在packa这个包中权限不够。
解决:提升DemoA的权限。提升到哪个权限。到public. ============================================================================
PackageDemo1.java:66: 错误: show()在DemoA中不是公共的; 无法从外部程序包中对其进行访问
d.show();
^
1 个错误 原因:show方法的权限不够,
解决:show用public修饰。 总结;
包与包之间的类在访问时,被访问的类以及成员都必须被public修饰。 注意;被public修饰的类或者接口,所属的java文件名必须和类或者接口名称一致。 包与包之间继承,父类可以给其他包中的子类提供一个特殊的权限protected,只有
继承为子类后,才可以访问的权限。 public protected default private
一个类中 ok ok ok ok
一个包中 ok ok ok
子类中 ok ok
不同包中 ok 包与包之中访问只有两种权限可以用,public protected(该权限只能给不同包中的子类使用。) =================================================================================
包的出现导致类的名称过长,导致书写不方便,咋办?
可以通过关键字来解决,import 导入。
import作用简化类名书写。省略包名。 特殊情况一:
packa\packaa\DemoAA
\DemoA.class
import packa.*;//仅仅指的是使用的类所属的包是packa下的。不会导入packa中子包中的类。
如果要使用DemoAA
import packa.packaa.*;
new DemoAA(); 特殊情况二://不同包中有了相同名称的类。使用该类时,必须指定包名。
packa\Demo.class
packb\Demo.class import packa.Demo;
import packb.Demo; new packa.Demo();
*/
//import packa.DemoA; //import packa.*不建议这样写。
import packa.*; class PackageDemo1
{
public static void main(String[] args)
{
// packa.DemoA d = new packa.DemoA();
DemoA d = new DemoA();
d.show(); //packfu.DemoFu d1 = new packfu.DemoFu();
//d1.showFu();
System.out.println("Hello World!");
}
}
package packa; public class DemoA extends packfu.DemoFu
{
public void show()
{
showFu();
System.out.println("demoa show run");
}
}
package packfu;
public class DemoFu
{
/*public*/protected/*保护*/ void showFu()
{
System.out.println("demofu show run");
}
}
/*
Jar包:java中的压缩包。 直接将jar包导入到classpath路径中即可。 */
package pack; class JarDemo
{
public static void main(String[] args)
{
System.out.println("Hello jar!");
}
} //day13/pack/JarDemo.class ---jar--->day13/haha.jar/pack/JarDemo.class