一、Java的几种常见的设计模式(共23种)
单列设计模式:::★★★★★
作用:保证一个类在内存中的对象唯一性
方法(如何保证对象的唯一性):
1,因为创建对象都需要构造函数初始化,只要将本类中的构造函数私有化,其他程序就无法再创建该类对象;
2,就在类中创建一个本类的对象;
3,定义一个方法,返回该对象,让其他程序可以通过方法就得到本类对象。(作用:可控)
代码体现:1,私有化构造函数;2,创建私有并静态的本类对象;3,定义公有并静态的方法,返回该对象。
——————————————————————————————
饿汉式和懒汉式的实现
二、继承
好处:
1:提高了代码的复用性。
2:让类与类之间产生了关系,提供了另一个特征多态的前提。
java不支持多继承,但是java支持多重继承。A继承B B继承C C继承D。
子类出现后的变化:
This:代表是本类类型的对象引用。
Super:代表是子类所属的父类中的内存空间引用。
super(): 表示父类的构造函数,并会调用于参数相对应的父类中的构造函数。super():是在调用父类中空参数的构造函数。
★★★注意:★★★
1.子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();
2.如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数。
3.如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数。
super()和this()不能同时出现的构造函数中。
★★★两个语句只能有一个定义在第一行,所以只能出现其中一个。
三、final特点:
1.这个关键字是一个修饰符,可以修饰类,方法,变量。
2.被final修饰的类是一个最终类,不可以被继承。
3.被final修饰的方法是一个最终方法,不可以被覆盖。
4.被final修饰的变量是一个常量,只能赋值一次。
四.多态★★★★★
抽象类:
1.抽象方法只能定义在抽象类中,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。
2.抽象方法只定义方法声明,并不定义方法实现。
3.抽象类不可以被创建对象(实例化)。
4.只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。
★★抽象类的细节:
抽象关键字abstract和哪些不可以共存?final , private , static
抽象类中可不可以不定义抽象方法?可以。抽象方法目的仅仅为了不让该类创建对象。
接口::★★★★
1.接口中有抽象方法,说明接口不可以实例化。接口的子类必须实现了接口中所有的抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。
2.类与类之间存在着继承关系,类与接口中间存在的是实现关系。继承用extends ;实现用implements ;
3.接口和类不一样的地方,就是,接口可以被多实现,这就是多继承改良后的结果。java将多继承机制通过多现实来体现。
4.一个类在继承另一个类的同时,还可以实现多个接口。所以接口的出现避免了单继承的局限性。还可以将类进行功能的扩展。
5.其实java中是有多继承的。接口与接口之间存在着继承关系,接口可以多继承接口。
抽象类和接口的相同与不同点:
相同:都不能实例化;可以被继承;包含抽象方法;子类必须实现方法的实例化。
不同:接口可以多继承,抽象类不能行;接口中的成员变量只能是public static final类型,抽象类中可以是各种类型;接口只能定义抽象方法,而抽象类都可以。
五、异常处理★★★★
1.异常分为两种:编译时异常①和运行时异常②
①只要是Exception及其子类都是编译时被检测的异常。
②其中Exception有一个特殊的子类RuntimeException,以及RuntimeException的子类是运行异常,也就说这个异常是编译时不被检查的异常。
2.一般的异常可以直接用
try{
可能异常的代码;
}catch(所属的异常类型 e){
System.out.println(e.getMessage());//获取的是异常的信息。
System.out.println(e.toString());//获取的是异常的名字+异常的信息。
e.printStackTrace();//打印异常在堆栈中信息;异常名称+异常信息+异常的位置。
}finally{
不管是否异常,都必须要执行的语句;
}
3. 对于throws和throw的区别
①throws是声明一个方法可能抛出的异常,这个异常可能是系统定义的,也可以是自己定义的异常
②throw是针对对象的做法。抛出的异常,这个异常可能是系统定义的,也可以是自己定义的异常
4.★定义异常处理时,什么时候定义try,什么时候定义throws呢?
1.功能内部如果出现异常,如果内部可以处理,就用try;
2.如果功能内部处理不了,就必须声明出来,让调用者处理。
★★注意:
1.如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws。
2.如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。
六、多线程
1.执行多线程的条件:
程序需要同时执行两个或两个以上的任务
程序需要执行一些需要等代的任务时。如:用户的输入、文件的读写....
需要一些后台运行的程序时
2.进程:正在进行中的程序。其实进程就是一个应用程序运行时的内存分配空间。
3.线程:其实就是进程中一个程序执行控制单元,一条执行路径。进程负责的是应用程序的空间的标示。线程负责的是应用程序的执行顺序。
4.start方法作用:1)、启动了线程;2)、让jvm调用了run方法
5.★★★★创建多线程的方法
①继承Thread和②实现Runable接口的区别
继承:程序将代码放在Thread子类的run()方法中。
实现:将代码存放在Runable接口的子类的run()方法中
实现Runnable的好处:
避免了单继承的局限性
实现共享资源。
③.collable接口
强大之处:可以有返回值、可以抛出异常,并且被外界捕获,获取异常信息、支持泛型(暂时未学)
④使用线程池(暂时未掌握)
/*
Thread类的相关方法
void start(): 启动线程,并执行对象的run()方法
run(): 线程在被调度时执行的操作,要执行的代码放在这里
String getName(): 返回线程的名称
void setName(String name):设置该线程名称
static Thread currentThread(): 返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类
static void yield():线程让步暂停当前正在执行的线程,把执行机会让给优先级相同或更高的线程若队列中没有同优先级的线程,忽略此方法
join() :当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止低优先级的线程也可以获得执行
static void sleep(long millis):(指定时间:毫秒)令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
stop(): 强制线程生命期结束,不推荐使用
boolean isAlive():返回boolean,判断线程是否还活着
*/
6.出现线程安全的原因:当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。
7.解决线程安全问题的几种方法★★:同步方法、同步代码块、lock锁
//lock锁
class A{
private final ReentrantLock lock = new ReenTrantLock();
public void m(){
lock.lock();
try{
//保证线程安全的代码;
}
finally{
lock.unlock();//必须执行的步骤,解锁
}
}
}
//注意:如果同步代码有异常,要将unlock()写入finally语句块
8.synchronized的锁是什么?
任意对象都可以作为同步锁。所有对象都自动含有单一的锁(监视器)。
同步方法的锁:静态方法(类名.class)、非静态方法(this)
同步代码块:自己指定,很多时候也是指定为this或类名.class
/*
synchronized(互斥锁)
可解决线程安全问题
第一种:解决同步代码块的问题
//当某个对象被synchronized修饰时,表示该对象在某一时刻只能被一个线程所访问
synchronized (对象){
//需要被同步的代码块
}
第二种:synchronized还可以放在方法声明中,表示整个方法为同步方法。
例如:
public synchronized void show (String name){
….
}
*/
9.synchronized 与 Lock 的对比
1. Lock是显式锁(手动开启和关闭锁,别忘记关闭锁),synchronized是
隐式锁,出了作用域自动释放
2. Lock只有代码块锁,synchronized有代码块锁和方法锁
3. 使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有
更好的扩展性(提供更多的子类)
10.sleep和wait的异同
相同点:都能使当前线程进入阻塞状态
不同点:两者的使用位置不同,Thread类中声明sleep()...Object类中声明wait();使用场景不同,wait只能在同步代码块或同步方法中使用,sleep哪里都可以。