JAVA基础笔记(2)

Object

Object: 是所有对象的直接或间接父类

该类中定义了所有对象的功能

如果自定义类中也有比较相同的功能,没有必要重新定义

只要沿袭父类中的功能,建立自己特有比较内容即可,这就是覆盖

1.内部类

1.内部类的访问规则

1)内部类可以直接访问外部类中的成员,包括私有

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

2)外部类要访问内部类,必须建立内部对象

直接访问内部类中的成员Outer.Inner in =  new Outer().new Inner();

2.访问格式:

当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类。

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

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

3.当内部类在成员位置上就可以被成员修饰符所修饰

比如:private 将内部类在外部类中进行封装

static  :内部类就具备了静态特性  当内部类被静态修饰后只能访问外部类中的静态成员,出现了访问局限

在外部其他类中如何直接访问static内部类的非静态成员呢?

new Outer.Inner() .function();

在外部其他类中如何直接访问static内部类的静态成员呢?

Outer.Inner.function();

4.注意:当内部类中定义了静态成员,该内部类必须是static的

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

5.当描述事物时:事物的内部还有事物,该事物用内部类来描述

因为内部事务在使用外部事物的内容。

匿名内部类

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

2.定义匿名内部类的前提

内部类必须是继承一个类或者实现接口

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

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

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

2.异常

1.异常:就是程序在运行时出现的不正常情况

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

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

对于问题的划分:两种 :一种是严重的问题  一种是非严重的问题

对于严重的问题,java通过Error类进行描述 ,对于Error一般不编写针对性的代码对其进行处理

对于非严重的,java通过Exception类进行描述 ,对于Exception可以通过使用真对象的处理方式进行处理

无论Error或者Exception都具有一些共性的内容

比如:不正常情况的信息,引发原因等

2.异常的处理

java提供特有的语句进行处理

try{需要被检测的代码 }  catch(异常类 变量(Exception e)){处理异常的代码(处理方式)} finally{一定会执行的语句}

e.printStackTrace();//打印异常详细信息,打印异常的堆栈的跟踪信息

3.对捕获到的异常对象进行常见方法进行操作

对多异常的处理:

1.声明异常时建议声明更为具体的异常,这样处理的可以更具体

2.对方声明几个异常,就对应几个catch块

如果多个catch块中的异常出现继承关系,父类以后吃那个catch块放在最下边

因为项目中会出现特有的问题 而这些问题并未被Java所描述并封装为对象

所以对于这些特有的问题可以按照java的对问题封装的思想

将特有的问题,进行自定义的异常封装

自定义异常:

需求:在本程序中,对于除数是-1,也是错误的是无法进行运算的。

那么就需要对这个问题进行自定义的描述

当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作

要么在内部try catch

要么在函数上声明让调用者处理

一般情况在 函数内部出现异常 函数上需要声明

发现打印的结果中只有异常的名称,却没有异常的信息。

因为自定义的异常并未定义信息

如何定义异常信息呢?

1.class FushuException extends Exception{

如何定义异常信息呢?

复写父类的

/*

private String msg;

FushuException(String msg){

this.msg = msg;

public String getmessage(){

return msg;

}

*/

2.如何定义异常信息呢?

因为父类中已经把异常信息的操作都完成了。

所以子类只要在构造时,将异常信息传递给父类通过super语句

那么就可以直接通过getmessage方法获取自定义的异常

class FuShuException extends Exception {

private int value;//错误的负数

FuShuException (String msg,int value){

super (msg);

this.value = value;

}

public int getValue(){

return  value;

}

if(b<0){

throw new FushuException();//手动通过throw关键字抛出一个自定义异常对象

}

//自定义异常必须继承Exception

继承Exception的原因

异常类 和 异常对象都被抛出

他们都具备可抛性,这个可抛性时throwable这个体系中独有的特点

只有这个体系中的类和对象才可以被throws 和  throw 操作

throws和throw的区别

throws使用在函数上  throw使用在函数内

class Demo{

int div (int a ,int b)throws FuShuException{

if(b<0)

throw new FuShuException(“出现了除数是负数的情况--/by fushu”,b);

return a/b;

Exception 中有一个特殊的子类异常RuntimeException运行时异常

如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过

如果在函数上声明了该异常,调用者可以不用进行处理,编译一样通过

之所以不用在函数声明,是因为不需要让调用者处理。

当该异常发生,希望程序停止,因为在运行时,出现了无法继续运算的情况。希望停止程序后,对代码进行修正

自定义异常时:如果该异常的发生,无法在继续进行运算,就让自定义异常继承RuntimeException

对于异常分两种

1.编译时被监测的异常  (如果没有被声明编译失败)

2.编译时不被监测的异常(运行时异常,RuntimeException以及其子类)

异常在子父类覆盖中的体现

1.子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类

2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集

3.如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常

如果子类方法发生了异常,就必须进行try处理,不能抛出

异常总结:异常是对问题的描述。将问题进行对象的封装

异常体系: Throwable

--Error

--Exception

-- RuntimeException

异常的体系特点:异常体系中的所有类以及建立的对象都具备可抛性

也就是说可以被throw和throws关键字所操作

只有异常体系具备这个特点

throw和throws的用法:

throw定义在函数内部,用于抛出异常对象

throws定义在函数上,用于抛出异常对象,可以抛出多个用逗号隔开。

当函数内容有throw抛出异常对象,并未进行try处理,必须要在函数上声明,都在编译时失败。

注意:RuntimeException除外,也就是说函数内部如果抛出RuntimeException异常,函数上可以不用声明。

如果函数声明了异常。调用者需要进行处理,处理方法可以throws可以try。

异常有两种:

1.编译时被监测异常: 该异常在编译时如果处理(没有抛也没有try),编译失败。该异常被标识,代表这可以被处理。

2.运行时异常(编译时不监测)在编译时,不需要处理,编译器检查 。该异常的发生,建议不处理,让程序停止,需要对代码进行修正。

异常处理语句

try    需要被监测的代码

catch  处理异常的代码

finally 一定会执行的代码

注意  1.finally里通常定义关闭资源代码,因为资源必须被释放

2.finally只有一种情况不会执行  System.exit(0)系统退出  finally里面的代码不会执行

自定义异常 :

定义类继承Exception或者RuntimeException

1.为了让该自定义类具备可抛性

2.让该类具备操作异常的共性方法

当要定义自定义异常的信息时,可以使用父类已经定义好的功能

将异常信息传递给父类的构造函数

class MyException extends Exception{

MyException(String message)

super(message);

自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。

异常的好处:

1.将问题进行封装

2.将正常流程代码和问题处理代码相分离,方便阅读

异常的处理原则:

1.处理方式有两种:try或者throws

2.调用到抛出异常的功能时,抛出几个就处理几个

3.多个catch,父类的catch放到最下面。

4.catch 内,需要定义针对性的处理方式,不要简单的定义printStackTrace,输出语句

也不要不写

当捕获到的异常,本功能处理不了时,可以继续在catch中抛出

try{throw new Aexception() }

catch(AException e){ throw e}

如果该异常处理不了,但并不属于该功能的异常

可以将异常转换后,在抛出和该功能相关的异常。

或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去

当调用者知道,并处理,也可以将捕获异常处理后,转换新的异常

try{throw new Aexception() }

catch(AException e){

//对AException异常的处理

throw new BException();

比如:汇款的例子

异常的注意事项:

在子父类覆盖时,

1.子类抛出的异常必须是父类异常的子类或者子集;

2.如果父类或者接口没有异常抛出时,子类覆盖出现异常时,只能try不能抛

线程的安全问题:原因

当多条语句在操作统一线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,

另一个线程参与进来执行,导致共享数据的错误

解决办法:

对多条操作共享数据的语句,只能让一个线程都执行完。在执行过程中,其他线程不可以参与执行

java对于多线程的安全问题提供了专业的解决方式

就是同步代码块 。

synchronized(对象){需要被同步的代码}

对象如同锁。持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取cpu的获取权,也进不去,因为没有获取锁。

好处:解决了多线程安全问题

弊端:多个线程需要判断锁。较为消耗资源

要保证多线程安全,必须保证synchronized(对象)为一个  为一个锁

如果同步函数被静态修饰后, 使用的锁是什么呢?

通过验证,发现不在是this,因为静态方法中也不可以定义this

静态进内存时,内存中没有本类对象,但是一定有该类对应的字码节对象 类名.class

静态的同步方法使用的锁是该方法所在类的字节码文件对象  类名.class

静态方法不能访问非静态成员

死锁:同步中嵌套同步

线程间通讯

其实就是多个线程在操作统一个资源,但是操作的动作不同

notifyAll();

wait  notify() notifyAll()

都使用在同步中,因为要对持有监视器(锁)的线程操作

所以要使用在同步中,因为只有同步才具有锁

为什么这些操作线程的方法要定义Object类中呢?

因为这些方法在操作同步中线程时,都必须要标识她们所操作线程只有的锁

只有同一个锁上的被等待的线程,可以被同一个锁上notify唤醒。

不可以对不同锁中的线程进行唤醒。

也就是说等待和唤醒必须是同一个锁

而锁是可以任意对象,所以可以被任意对象调用的方法定义Object类中

你可能感兴趣的:(JAVA基础笔记(2))