您的位置:首页 > 职场人生

黑马程序员--内部类以及异常基础知识篇

2014-04-07 11:52 246 查看
内部类

----------------------------------------------------------------------------------------------------------------------

定义:将一个类定义在另外一个类的里面,对于里面的那个类就成为内部类(也称为内置类

或者嵌套类);

内部类访问规则:

1.      内部类可以直接访问外部类中的成员,包括私有的;因为内部类持有了外部类的引用,格式为:

“外部类名.this. ”;但是当内部类中也有一个与外部类名称相同的成员时,他会优先调用自己的成员!

2.      外部类要访问内部类,必须建立内部类的对象才可以访问;

class Outer{
private int x = 3;
class Inner{
void function(){
System.out.println("inner"+x);
//因为内部类持有外部类的引用,在x前面省略了“Outer.this.”
//所以内部类直接访问了外部类的成员!
}
}
void method(){
Inner in = new Inner(); //外部类先创建了内部类的实例对象
in. function(); //然后才访问内部类的成员函数;
}
}

访问格式:

1. 当内部类定义在外部类的成员位置上,而且是非私有的时,可以通过以下方式直接访问内部类中的成员:

格式:外部类名. 内部类名 变量名 =  new  外部类对象.new 内部类对象;

                例如:Outer.Inner  in  = new Outer( ).Inner( );

                      in.function( );

2. 当内部类在成员位置上时,就可以用成员修饰符来修饰内部类:

   比如:private修饰:将内部类进行了外部类封装,不可以再new内部类对象;

        static修饰:内部类就具备了静态的特性,这样一来他就只能访问外部类中的静态成员了,同时其他

外部类就可以通过:new Outer.Inner().function( );来访问内部类中的成员了

          注意:当内部类中定义了静态成员,那么该内部类必须是静态的;

                             当外部类中静态方法访问内部类时,该内部类必须是静态的。

内部类的定义原则:类是用于描述事物的,当描述事物时,事物的内部还有事物,那么该事物就用内部类来

描述,因为内部事物在使用外部事物的内容。

---------------------------------------

匿名内部类

       当内部类被定义在了局部时,就成为匿名内部类;比如将一个类的实例对象作为某个函数的实际参数进行

传递,那么这个被当作实际参数的类就是一个匿名内部类-----当然这种情形下的使用还有一定的条件!

匿名内部类的定义以及一些要求:

1.       匿名内部类其实就是内部类的简写格式;

2.       定义匿名内部类,该内部类必须继承一个类或者实现一个接口;

3.       匿名内部类的格式:new 父类或者接口(){ 定义子类内容 };

4.       其实匿名内部类就是一个匿名子类对象,只不过这个对象有点胖,可以理解为带内容的对象!

5.       匿名内部类中定义的方法最好不要超过3个!

Object类

----------------------------------------------------------------------------------------------------------------------

       他是所有对象的直接或者间接父类,传说中的上帝(即使你随便定义一个类,即使没有用extends关键字去

继承Object,他也是Object的子类)。该类中定义的都是所有对象都具备的功能;

       该类已经提供了比较对象是否相同的功能,所以其他子类没有必要重新定义,只需要直接拿来用,或者

根据自身的需求复写Objext中的equals()方法,定义新的函数体就行了;

java认为所有对象都可以变成字符串,于是在Object中定义了一个toString( );他打印的是它的值等于:

getClass().getName() + '@' +Integer.toHexString(hashCode()),

而在具体使用中我们可以根据需要复写该方法,答应出我们想要的字符串信息!

异常

---------------------------------------------------------------------------------------------------------------------

定义:异常就是程序在运行是出现的不正常情况;

由来:问题也是实际生活中的一种具体的事物,也可以通过java的类的形式进行描述,并封装成对象,其实

就是java对不正常的情况进行描述后的对象体现;

简而言之:把问题封装成对象就是异常!

异常体系一览:

       Throwable

              |---------Error

              |---------Exception

                     |---------RuntimeException

       异常体系的特点:异常体系中所有的类以及建立的对象都具有可抛性,也就是说可以被throws和throw

关键字所操作(只有异常体系具备这个特点)。

对于问题的划分:

严重的问题:java通过Error类来描述;对于Error一般是不会编写针对性代码进行处理。

非严重的问题:java通过Exception类进行描述,对于Exception可以使用针对性的代码进行处理!

Error就是犯了十恶不赦犯罪的恶人,对于他们没有改造的可能,所以直接枪毙;而

Exception是还有改造可能的普通罪犯,只要处理得当,他们是可以走上正途,为社会主义事业做贡献的!

       Throwable类是 Java 语言中所有错误或异常的父类。只有当对象是此类(或其子类之一)的实例时,才能

通过 Java 虚拟机或者 Java的throw语句抛出。类似地,只有此类或其子类之一才可以是 catch 子句中的参数类型。

       我们着重学习的是对于异常的处理:

异常的处理格式:try{

    需要被检测的代码;

//(可以是多条被检测代码,对应就应该有多个catch块!)

}catch(异常类 
变脸名){

       处理异常的代码(处理方式);

/*对捕获到的异常的常见操作方法:

例如:catch(Exception  e){

System.out.println(“被除数除以零了!”);

System.out.println(e.getMassage());  //异常信息;

System.out.println(e.toString());  //异常名称,异常信息;

e.printstackTrace( );  //直接打印异常名称,异常信息以及异常位置

}*/

}finally{

       
一定会执行的语句;(通常情况是关闭底层系统资源)

}



对于一个有可能出现异常的方法,我们有两种处理方式:

一是:提前做好处理准备,也就是利用try{ }catch( ){ }语句,一旦这个问题发生了,程序会立刻将他

解决了,那么程序就不会因为这个问题而终止运行;

二是:在这个方法上贴一个标签,告诉调用者:我这个方法有可能出现问题,你在使用时,需要自行

处理,或者将产生的问题扔给你的上一级,让他处理;如果这个问题在整个调用链中都没有人

用try{ }catch( ){ }语句来处理,那么该问题最终会被扔给虚拟机,虚拟机有一套默认的处理方式,

将该问题处理了;

也就是说:当一个函数内部抛出了一个编译时被检测异常,那么必须对这个异常进行处理,要么在函数

内部进行try-catch处理;要么在函数上申明,由调用者进行处理!

那么如何给方法贴一个有问题的申明标签呢?如何将问题抛给调用者或者上一级呢?

       这是通过在需要抛出问题的函数上添加一个“throws
 XxxException”来完成的;

throw和throws的区别:

       throws用于函数上,可以跟多个异常类,各个异常类之间用逗号隔开;

       throw用在函数内;后边跟的是异常对象;

我们还知道,在一个类中可能有多个方法,而万一多个方法都有可能发生问题咋处理呢?

这就是多异常的情况了,如果在本类中将问题全部都处理的话,那么每个函数中都用

try{ }catch( ){ }语句来处理就OK了;

但是如果是调用其他类中声明了有多个异常,原则上:对方声明有几个异常,那么就应该有多少个catch块

并且如果多个catch块中的异常出现了继承关系的话,那么父类异常catch块必须放在最下面,否则他会将子类

catch块要接收的问题也给接收处理了,那么子类catch块就无法捕捉异常,就多余了,这种情况,编译器是不

会让编译通过的!此外,千万不要搞双保险,对于一个异常用两个catch块同时去处理,这样一来,当一个异

常出现时,被一个catch块处理了,函数也就停止了,那么另外一个catch块是不会捕捉到异常的,这种情况,

编译器同样是是不会让编译通过的!

----------------------------------------------------------------------------------------------------------------------

自定义异常:

       因为项目中有可能出现特有的问题,而这个问题在java的类库中并没有进行过描述和封装,自然也就不能

用已有的异常来捕获和处理;为了弥补这个漏洞,我们可以自己定义一个异常类,来描述和封装这个特有的问

题,并通过异常处理机制处理掉这个问题;

如何自定义异常呢?

       首先,该异常类必须继承Exception(当然继承Throwable或者Error也可以,但不常见!),

因为只有这样我们自定义的异常类才可以使用异常处理机制(也就是throw和throws的操作)

对于自定义异常如何定义异常信息呢?

       因为自定义异常的父类已经把对异常信息的操作完成了,所以子类只需要在构造函数中将异常信息通过

super语句传递给父类,那么就可以通过getMessage方法获取自定义的异常信息了:

class FuShuException  extends  Exception{

       FuShuException(String  异常信息){

       super(异常信息);

}

}

-------------------------------------------------

RuntimeException:

       上文中我们说到有编译时被检测异常;那么对应的就有编译时不被检测异常,

而RuntimeException及其子类就是编译时不被检测异常;

       引言:我们知道通过异常处理机制将异常捕获并且处理以后,程序就可以继续正常的运行了,但是有时候

我们希望一个异常被抛出后,处理机制不要自行处理,而是将程序停下来,由程序员对代码进行相应的修改,

从而将问题解决掉;对于这种情况就需要用到RuntimeException或者其子类;

       用RuntimeException或者其子类来处理异常就是告诉编译器,尽管我没有将函数中抛出的异常处理掉,

但是你给我开个后门,也让我编译通过,到时候出了问题,我自己来解决,就不麻烦你了。所以对于

RuntimeException或者其子类,当函数中抛出了问题,不需要用try-catch处理,或者在函数上申明!

(开个玩笑:RuntimeException或者其子类就是赖昌星的远华走私集团,而编译器就是海关,所有入关的

货物都需要安全认证---try-catch处理机制;或者有免检认证---throws标志;而走私集团他两样都没有,但是

他买通了海关的一部分工作人员,所以他也把货物弄到了境内!)

-------------------------------------------------

finally代码块:

    当一个代码发生了异常,即使被try-catch处理了,但是该代码下面的内容也执行不了了!

public class ExceptionTest {
public static void main(String[ ] args) {
try{
int x =9/0; //此处抛出一个异常
System.out.println(x); //执行不到!
System.out.println("哈哈哈"); //执行不到!
}catch(Exception e){
System.out.println("除以零了"); //catch块捕获到异常,并进行了处理!
}
}
}


我们想一想如果在抛出异常的代码下方是关闭底层资源或者关闭数据库的代码,那由于前面异常的原因,

这些代码将永远无法执行到。所以为了避免这种情况的发生,java提供了一种补救措施,那就是finally代码块:

它里面封装的是一定会执行的代码。这样一来即使前面发生了异常,我们还是可以关闭数据库或者底层资源;

当然,有一种情况下,finally代码块中的代码是执行不到的:那就是程序先执行了:System.exit(0 )。
这句代码会将Jvm结束,自然就不会去执行finally代码块中的代码了。

处理语句的常见格式:
    第一种格式:try{ } catch( ){ };
    第二种格式:try{ } catch( ){ }finally{};
    第三种格式:try{ } finally{};
记住一点:catch块是用于处理异常的,如果没有catch就代表了异常没有被处理,如果该异常是检测时异常
(也就是非RuntimeException及其子类),那么在函数上必须声明!

------------------------------------------------------------------------------
覆盖时异常的特点:
1.  子类在覆盖父类时,如果父类的方法抛出了异常,那么子类的覆盖方法只能抛出父类的异常,或者该
异常的子类或者不抛(即子类中不可以抛出父类中没有的异常!);
对于这一点可以通过多态的使用来说明,当调用者调用父类时,发现父类声明的有异常,于是调用者用
try-catch处理了,当调用者再接受了一个子类对象,如果这个子类抛出了比父类更宽的异常,那么调用者的
try-catch将处理不了-----早期的程序不能处理后期发生的新异常;class Test{
void function(Fu f){ //多态,如果父类接受一个子类对象;
try{
f.method( ); //使用子类的method()方法;若抛出异常
}catch(AException e){
//必须是父类抛出的异常或者其子类异常,否则无法捕捉子类抛出的异常进行处理
e.printstacktrace();
}
}
}

2.  如果父类中抛出了多个异常,那么子类在覆盖方法时,只能抛出父类异常的子集;
3.  如果父类或者接口没有抛出异常,那么子类在覆盖时,也不可以抛出异常,
即使有了异常也要在内部消化处理掉;
但是有一种情况即使子类抛出了父类中没有的异常,编译器也仍然会通过,那就是子类抛出了
RuntimeException或者其子类异常;因为这种异常不需要处理或者声明!

------------------------------------------------------------------------------
包package (类似于文件夹)
1.    它的作用是对类文件进行分类管理,就像两个同名文件不能存在于同一个文件夹中一样,可以在两个包中,
分别存放两个同名的类文件;
2.    给类提供了多层命名空间,类名的全称是:包名.类名;
3.    他必须写在程序代码的第一行,并且包名中所有的字母均小写;
4.    包其实也是一种封装形式;
在DOS命令行中,需要通过键入特定格式的命令来新建一个包:
编译时:
D:\java0217\day10\javac
-d .Demo.java
这一步是新建了一个包,同时编译java源文件;
运行时:
D:\java0217\day10\javac
包名.Demo.java
包与包之间的访问:
a.    包与包之间进行访问,被访问的包中的类以及类中的成员需要别public修饰;
b.    不同包中的子类才可以访问父类中被protected权限修饰的成员;
c.    包与包之间可以使用的权限修饰符只有:public和protected两种;
import关键字:
    前面我们讲过了,将类文件放在包中以后,那么类名就变成了:包名.类名;这样一来书写起来就超级麻烦
了,为了简化书写,java提供了import这个关键字,只要用他将包导入到这个类中,那么本类在使用包中的类
时就不需要写包名了,直呼其名就可以了!
------------------------------------------------------------------------------
jar包:
    java的压缩包,方便项目的携带,方便使用。只要在casspath中设置pathjar路径即可;数据库驱动,
SSH框架等以jar包的形式体现;例如:有两个文件夹分别为packageA和packageB想要将他们放到一个
名为yasuobao的jar包中,只要进行如下操作便可以了:
首先进入到两个文件夹所在的目录下:c:\cd  myclass
    然后按照此操作打包c:\myclass>jar -cf
yasuobao.jar packageA
packageB
其中-c:是创建归档文件  -f:是指定归档文件名
    如果想要查看jar文件中的具体内容,可以通过以下操作:
        c:\myclass>jar-tf yasuobao.jar  >c:\1.txt
        -t:是查看jar包的指令;
        >c:\1.txt:是将信息输出到c盘下的1.txt文件中去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息