黑马程序员:java学习要点-内部类和异常

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1.1. 内部类

1.1.1. 将一个类定义在另一个类的里面,对里面那个就称为内部类

内部类可以直接访问外部类中的成员

外部类通过创建内部类的对象完成内部类成员的访问

内部类通常用于设计上,在描述事物的时候,事物中还有具体的事物,而且这个事物还在直接访问所属事物中的内容

这时就可以把这个内部事物用内部类来进行描述。

数据共享区————>方法表   静态区   常量池


静态是个成员修饰符,不能存在于局部

成员修饰符都不能存在于局部——

内部类在成员位置的时候,可以用成员修饰符!


匿名内部类:其实就是内部类没有名字,就是内部类的简写格式

简写都是有前提的

匿名内部类的前提:

必须要继承一个外部类或者实现一个外部接口

匿名内部类其实就是一个子类对象,而且这个对象有点胖

new Demo();//Demo类对象

new Demo()//Demo类的子类对象

{

public void show(){}

}


匿名内部类的格式:

new 父类类型(){子类内容}

内部类之所以可以访问外部类中的成员,是因为内部类其实持有了外部类的一个引用,外部类名.this.成员名

*/

class Outer

{

int num=4;

static int otherNum=2;

class Inner

{

int num=5;

void show()

{

System.out.println(Outer.this.num);//不重名的时候可以省略

}

}

//静态内部类

static  class OtherInner

{

public void show()//非静态成员

{

System.out.println("静态内部类-非静态方法"+otherNum);

}

public static void showNum()

{

System.out.println("静态内部类-静态方法"+otherNum);

}

}

public void method()

{

Inner in=new Inner();

in.show();

}

}

class InnerDemo

{

public static void main(String[] args) 

{

Outer outer=new Outer();

outer.method();

//内部类不被私有的时候可以如下访问内部类,但是内部类一般被看做成员来私有

Outer.Inner outin=new Outer().new Inner();

outin.show();

//静态内部类,如何访问其中的非静态方法?

//当内部类被静态修饰,其实就是相当于一个外部类

Outer.OtherInner in =new Outer.OtherInner();

in.show();

//访问静态内部类之中静态方法

Outer.OtherInner.showNum();

//非静态内部类之中,不可以定义静态成员

//总之,体系中,静态向上不走对象,静态向下有非静态之前不走对象,之后要走对象

//静态之间不能断开,静态必须连续存在

//静态只能修饰成员位置的事物(成员或者内部类),他是不能修饰外部类的

}

}

1.1.2. 内部类定义在局部

内部类定义在局部不允许访问局部的变量,只能使用final修饰的局部变量

因为方法进出栈转换快,出栈之后,其中的局部变量不在存在内存中,所以下一个方法无法使用,而final修饰的的变量存在于数据共享区的常量池

public Object function()//不能使用AInner这个类名,因为外部都不知道

{

final int aa=10;

class AInner extends Object

//想使用内部类中特有内容,定义一个父类包含要使用的子类功能

{//子类继承该父类,并覆盖其中要使用的功能,然后用父类类型使用——多态

//对外隐藏子类类型,使用父类调用

public String toString()

{

return "aa="+aa;

}

}

return (new AInner());

}

public void test()

{

Object obj=function();

System.out.println(obj.toString());

}

匿名内部类什么时候使用?

函数的参数是接口类型时,而且该接口中的方法不超过2

这时可以往这个函数内传递一个匿名内部类

abstract class AbsDemo

{

abstract void show();

abstract void Ashow();

}

class XOuter

{

public void method()

{

//匿名内部类就是一个匿名子类对象

AbsDemo a=new AbsDemo()

{

public void show()

{

System.out.println("num=="+num);

}

public void Ashow(){

System.out.println("Ashow");

Bshow();

//该特有方法只在内部使用;非外部使用,不要起名字,直接使用

}

public void Bshow(){

//匿名内部类一般不写特有方法,如果写,只在内部使用

System.out.println("Bshow");

}

};

a.show();

a.Ashow();

}

}

class  NoNameInner

{

public static void main(String[] args) 

{

XOuter xo=new XOuter();

xo.method();

}

}


class InnerClass  

{

public static void main(String[] args) 

{

//new Inner();//???相当于this.new Inner();编译失败——this是非静态的

//Inner是外部类时,建立对象有什么不同?

method();//如果静态函数要访问内部类,该内部类必须是静态的

}

class Inner

{

}

public void method()//——该方法只能被对象使用,也就是this有指向

{

new Inner();//this.new Inner();这里this有指向,所以编译通过

}

}

1.2. 异常

1.2.1. 概述

异常:不正常

java在运行时期出现的不正常情况

java 按照面向对象的思想对问题进行描述和封装

将问题变成对象,里面包含着问题的名称,信息以及位置等

常见的问题有两种:

一种是可处理的

一种是通常不处理的

1.2.2. 异常体系

问题都有一些共性,不断向上抽取,就形成了体系

可以处理的问题都向上抽取到一个父类中:Exception

不可处理的问题向上抽取到一个父类中:Error——通常都是由JVM或者系统抛出的严重问题,改代码解决

无论错误还是异常都有名称,信息,位置等共性内容

向上抽取到Throwable(可抛)

1.2.3. 异常处理过程

下列程序中:??????异常的处理流程???画图

执行过程中,产生问题ArrayIndexOutOfBoundsException,就将问题

封装成对象,然后抛给调用者JVM,调用者JVM使用默认的处理机制,

将问题信息打印在控制台上,同时停止程序

异常抛给调用者,调用者可以处理也可以不处理,不处理的话,可以继续抛出......直到主函数不处理的话,异常被抛给虚拟机,虚拟机启用异常默认处理机制,输出并停止

可抛性——可以被throw或者throws关键字所操作。

如图

1.2.4. 自定义异常

对于体系中没有的异常,可以自定义该异常

函数发生异常,函数上不声明,是为了让调用者对代码进行修正。这种异常都是RuntimeException或者其子类

异常分两种:

一种是编译时需要被检测的异常,Exception及其子类

可以进行针对性的处理

一种是编译时不被检测的异常,RuntimeException(运行时异常)

通常不编写处理方式,直接让程序停止,为了让调用者进行代码的修正

意味着:我们在自定义异常的时候,可以继承Exception,也可以继承RuntimeException

对于针对性处理:??????异常的处理流程???画图

可以通过java提供的指定的处理代码完成try catch finally

try

{

//要检测的代码块

}

catch(异常类型 异常名)

{

//异常的处理代码

}

对方函数声明是什么异常,catch里就处理什么异常,这样才具备针对性;

对方抛出了多个异常,应该具有多个catch语句分别进行针对性处理

如果出现多个catch,父类catch放在最下面

异常抛出的基本原则:

功能中用throw关键字抛出异常,如果没有被catch处理,就必须用throws在函数上进行声明

注意:RuntimeException及其子类除外,也就是说,功能中throw抛出的是RuntimeException和其子类对象,函数上可以不用throws进行声明

声明的好处在于:让调用者预先定义进行处理方式

函数发生了问题:选择抛还是try catch

功能内部可以处理就catch,不可以处理——必须throws

throwthrows区别?

throw用在函数内,用于抛出异常,后面跟的都是异常的对象

throws用在函数上,用于声明异常,后面跟的都是异常类,而且可以跟多个,中间逗号隔开

小细节:

throw在函数中的出现,可以用于结束函数的运行

void show() throws Exception

{

throw new Exception();

sop("haha");//执行不到

}

对异常进行处理,可能出现嵌套try-catch??????

对可能出现异常的方法,可以在当前函数上throws,让调用者处理

或者在当前函数内,用try-catch对异常进行处理

catch一个异常,就相当于处理了该异常,没catch某个异常,就是没处理该异常

1.2.5. finally

一定会被执行的代码

finally代码块用于关闭资源

只有JVM被停止(System.exit(0);),finally才不会被执行

数据库连接的实例

try

{

连接数据库。

操作数据(在操作过程中出现意外----异常,程序跳转)

}

catch(异常 e)

{

}

finally

{

关闭数据库

}

1.2.6. try-catch-finally的组合方式

有需要关闭的资源就写finally

组合方式:

1try-catch-finally

2try-catch

3try-finally————其目的在于关闭资源。对发生的异常,可以throws声明让调用者处理

try

{throw new Exception()}——没处理,要声明

finally

{//关闭资源}

try

{throw new Exception()}

catch(Exception e)——处理了,就不必声明

{}

finally

{//关闭资源}

1.2.7. 异常覆盖的细节

1,子类在覆盖父类方法时,如果父类方法抛出异常

子类覆盖的方法只能抛出父类方法异常或其子类

2,父类方法如果抛出多个异常,子类在覆盖方法时

只能抛出父类方法异常的子集

3,如果父类中方法没有抛出异常(throws

子类在覆盖父类方法时,不能抛出异常

只能进行try-catch

万一处理不了,那就应该让程序停掉,让调用者知道

直接在catch中用throw抛出RuntimeException或者其子类

class Fu{void show(){}}

class Zi extends Fu

{

void show(){

try

{function();}//{throw new Exception ()}

catch(Exception e)

{throw new RuntimeException(); }//对捕捉到的异常自己没办法处理,所以抛出 //RuntimeException,让程序停止

}

void function() throws Exception

{}

}

2. package-

对类文件进行分类管理

对类提供多层命名(名称)空间

写在程序文件的第一行

类名的全称是:包名.类名

包也是一种封装形式

2.1. 包的作用:

1.分类管理类文件

2.对类提供了多层名称空间

2.2. 包的定义:

使用关键字package,定义包必须定义在源代码的第一行

包名全部小写

package mypack;//定义了一个名称为mypack的包

javac -d . PackageDemo.java

javac -d d:\myclass Package.java

2.3. 包的使用

1,使用包之后,类名要用全类名

2,设置classpath,告诉JVM  packa包的位置

3DemoA类在packa包中被访问的权限不够,将DemoApublic修饰

4,类之中的成员被访问的权限不够,把要访问的成员用public修饰

包与包之间不用public修饰,相当于封装

2.4. protected权限

继承了能用,不继承也能用?举例说明???

 

    范围        public protected default private 

同一个类中      ok ok ok ok  

同一包中   ok okok  

子类   ok  

不同包中        ok  

2.5. import关键字

import是简化类名书写的,导入之后可以不写全类名

package mypack;

//为了简化类名的书写,使用一个关键字import导入

import packa.DemoA;//导入packa包中的DemoA

import packa.*;//用到哪个类,就会去包中找,会比较慢!所以实际中会导入具体的类

//高级编辑器的一个快捷键

import packa.*;//导入packa包当前目录下的类,不导入包中的包

import packa.haha.*;//导入packa包的子包haha中的类

当导入的包中的类有重名的时候,使用该类是,必须使用全类名,包名.类名

2.6. Jar

java的压缩包

jar可以直接设置到classpath中去:set classpath=d:\myclass\jardemo.jar

之中的类可以直接使用


----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值