黑马程序员_毕向东JAVA基础_设计模式&异常处理机制

时间:2023-02-17 09:25:55

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------

单例设计模式

设计模式:解决某一类问题最行之有效的方法。

单例设计模式:解决一个类在内存只存在一个对象。分为饿汉式和懒汉式。

想要保证对象的:

1.为了避免其他程序过多建立该对象。先禁止其他程序建立该类对象。

2.为了让其他程序员可以访问到该类对象,只好在本类中,自定义一个对象。

3.为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

实现:

1.将构造函数私有化,无法创建实例对象。

2.在类中创建一个本类对象。

3.提供一个方法可以获取该对象。


对于事物该怎么描述,就怎么描述。当需要将该事物的对象保证在内存中唯一时,将上述三步加上即可。

<方法调用方式有对象和类名(静态)两种方式。>单例模式无法创建对象,只能使用静态调用的方法。

饿汉式:先初始化化对象。Single类一进内存,对象就被创建了。(建议使用)

class Single
{
//私有构造方法。
private Single(){}
//私有,静态的类自身的实例对象。
private static Single s = new Single();
//调用方法。
public static Single getInstance()
{
return s;
}
}


class SingleDemo
{
public static void main(String[] args)
{
Single ss = Single.getInstance();
}
}

变种形式:

class Single
{

//私有,静态的类自身实例
private static Single s = null;
//静态代码块
static
{
s = new Single();
}

//私有的构造方法
private Single(){}

//调用对象方法。
public static Single getInstance()
{
return s;
}
}



懒汉式:

对象是方法被调用时才初始化,也叫做对象的延时加载。

Single类进内存,对象还没有存在,只有调用了getInstance方法时,才建立对象。

class Single
{
//私有构造方法。
private Single(){}
private static Single s = null;
//调用方法。
public static Single getInstance()
{
if (s == null)
s = new single();
return s;
}
}


class SingleDemo
{
public static void main(String[] args)
{
Single ss = Single.getInstance();
}
}

多线程并发需同步

class Single  
{
//私有构造方法,不允许其他类创建对象
private Single(){};
private static Single s =null;
//提供获取对象的方法
public static Single getInstance()
{
//提高判断锁的效率不让每次都判断
if(s == null)
//多线程的同步操作,锁是自身的字节码
synchronized (Single.class)
{
if(s == null)
//自己创建对象
s = new Single();
}
return s;
}
}

死锁:多个线程同时被阻塞,他们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地堵塞,因此程序不可以正常终止。

  导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。“synchronized”关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性的访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。

  由于这个原因,在使用“synchronized”关键词时,很容易出现两个线程互相等待对方做出某个动作的情形。代码一是一个导致死锁的简单例子。


异常处理机制

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

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

异常的好处:

1.      将问题进行封装

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

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

对于严重的。java通过error类进行描述。

对于error一般不编写针对性的代码对其进行处理。

对于非严重的。java通过exception类进行描述。

  对于exception可以使用针对性的处理方式处理;比如,数据角标越界等。

无论error或者exception都具有一些共性内容。比如:不正常情况的信息,引发原因等。

throwable

|--error

|--exception

异常的处理

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

try
{
需要被检测的代码;
}
catch (异常类 变量)//多态性!!
{
处理异常的代码: (处理方式)//注意抛几个异常,这里面就要写几个处理处理方式。
}
finally
{
}
其实JVM默认的异常处理机制,就是在调用printStackTrace方法。打印异常的堆栈跟踪信息。


对多异常的处理。

1.声明异常时,建议声明更为具体的异常。这样处理的可以更具体。不要定义多余的。

2.对方声明几个异常,就应有几个catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。

建议:在进行catch处理时,catch中一定要定义具体的处理方式。不要简单定义一句e.printStackTrace,也不要简单的定义一句输出语句。

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

因为项目中会出现特有问题,而这些问题未被java所描述并封装成对象。所以对于这些特有问题可以按照java的对问题封装的思想。将特有问题进行自定义的异常封装。

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


当在函数内部出现了throw抛出异常对象,那么就必须给对应的处理动作。
要么在内部try catch处理。要么在函数上声明让调用者处理。
一般情况在,函数内部出现异常,函数上需要声明

发现打印的结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义信息。

如何定义异常信息呢?

因为父类中已经把异常信息的操作都完成了。所以父类只要在构造函数时,
将异常信息传递给父类通过super语句。那么就可以直接通过getMessage
方法获取自定义的异常信息。

自定义异常:
必须是自定义类继承Exception.
继承Exception的原因:异常体系有个特点:因为异常类和异常对象都需要被抛出。
他们都具备可抛性。这个可抛性是throwable体系中的独有特点。只有这个体系中
的类和对象,才可被throws和throw所操作。


这个体系:Error throwable exception.

throws和 throw的区别:throws使用在函数上。throw使用在函数内。

throws后面跟的是异常类。可以跟多个。用逗号隔开。
throw后面跟的是异常对象。





*/

class FuShuException extends Exception //目的为声明对象
{
int value ;

FuShuException(String msg , int value)//构造函数中传入msg。
{
super(msg);//通过super语句,传递给父类。
this.value = value;
}
public int getValue()
{
return value;
}
}

class Demo
{
int div(int a,int b)throws FuShuException//函数内部出现异常,在函数上声明。
{
if(b < 0)
throw new FuShuException("cddddd",b);//手动通过throw关键字,抛出自定义异常对象
return a/b;
}
}

class ExceptionDemo1
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(4,-1);
System.out.println("x="+x);

}
catch (FuShuException e)
{
System.out.println(e.toString());
System.out.println("除数是"+e.getValue());
}
}
}
/* exception中有个特殊的子类异常RuntimeException运行时异常 如果再函数内容抛出该异常,函数上可以不用声明,编译一样通过。 如果再函数上声明该异常,调用者可以不用进行处理。 之所以不用再函数上声明,是因为不需要让调用者处理, 当该异常发生,希望程序停止。因为在运行时,出现了 无法继续运行的情况,希望程序停止,对代码进行修正。 自定义异常时:如果该异常的发生时,无法再继续进行运算, 就让自定义异常继承RuntimException 对于异常分为两种: 1.编译时被检测的异常 2.编译时不被检测的异常(运行时异常。RuntimeException以及其子类)*/class FuShuException extends RuntimeException //目的为声明对象{int value ;FuShuException(String msg , int value)//构造函数中传入msg。{ super(msg);//通过super语句,传递给父类。 this.value = value;}public int getValue(){return value;}}class Demo{int div(int a,int b){if(b<0)throw new FuShuException("负数",b);if(b==0)throw new ArithmeticException("beioddd");return a/b;}}class ExceptionDemo11 {public static void main(String[] args) {Demo d = new Demo();int x = d.div(4,-1);System.out.println("Hello World!");}}

第一种格式:

try{}

catch()

{

}

第二种格式:

try{}

catch()

{

}

finally

{

}

第三种格式:

try{}

finally

{

}

finally存放的是一定会被执行的代码;通常同于关闭资源。

finally只有一种情况不会执行。当执行到System.exit(0);fianlly不会执行

如果问题被解决,外部没有声明标识,也可以编译通过。但是如果catch继续抛出问题,那么编译不通过。

catch是用于处理异常的,如果没有catch就代表异常没有处理,如果该异常是检测时异常,那么必须声明。


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

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

Exception

|--AException

|--BException

|--CException

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

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

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


异常体系:

体系特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字所操作。只有异常体系具备这个特点。

throw和throws的用法:

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

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

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

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

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

异常有两种:

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

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


不同包中的类如何访问?

 

包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。不同包中的子类还直接可以访问父类中被protected权限修饰的成员。

包与包之间只能使用的权限只有两种,public protected(只能给子类使用)

 

public

protected

default

private

同一个类中

Ok

Ok

Ok

Ok

同一个包中

Ok

Ok

Ok

 

子类

Ok

Ok

 

 

不同包中

Ok

 

 

 

 

一个.java文件中不能出现两个以上的公有类或接口。

 

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

Import导入的是包中的类

建议,不要写通配符*。

当导入不同包中有相同的重名类时,必须加包名。

 

建议定义包名不要重复,可以使用url来完成定义。因为url是唯一的。

 

Java的压缩包:方便项目携带。方便于使用,只要在classpath设置jar路径就行。

---------------------- ASP.Net+Android+IO开发S.Net培训、期待与您交流! ----------------------