面向对象高级(2)单例设计对象与代码块
面向对象高级(2) 单例设计模式、main方法与代码块
引言;
设计模式:特定环境下特定问题的处理方法。可理解为一种经典的可以参照的模板。单例设计模式则是只存在单个对象实例、且只有一种方法获取对象实例的一种设计模式。
单例设计模式
1、设计思路:
(1)封装构造器,将构造器私有化,即可达到无法在类的外部创建对象的目的。
(2)在类的内部创建实例
(3)使用getInstance方法获取实例,声明为static。
2、两种实现方式
(1)饿汉式;
public class single {
private String name;
private single(String name) {
this.name = name;
}
private static single single = new single("Lily");
public static single getInstance(){
return single;
}
}
(2)懒汉式:
public class Lazy {
private String time;
private Lazy(String time) {
this.time = time;
}
private static Lazy laziness;
public static Lazy getInstance(){
if(laziness==null)
laziness = new Lazy("all the time");
return laziness;
}
}
3、对比饿汉式与懒汉式
(1)饿汉式
- 特点:立即加载,即在使用类的时候已经将对象创建完毕。
- 优点:实现起来简单;没有多线程安全问题。
- 缺点:当类被加载的时候,会初始化static的实例,静态变量被创建并分配内存空间,从这以后,这个static的实例就一直占着这块内存,直到类被卸载时,静态变量被摧毁,并释放所占有的内存。因此在某些特定条件下会耗费内存。
(2)懒汉式
- 特点:延迟加载,即在调用静态方法时实例才被创建。
- 优点:实现起来比较简单;当类被加载的时候,static的实例未被创建并分配内存空间,当静态方法第一次被调用时,初始化实例变量,并分配内存,因此在某些特定条件下会节约内存。
- 缺点:在多线程环境中,这种实现方法是完全错误的,线程不安全,根本不能保证单例的唯一性。
- 说明:在多线程章节,会将懒汉式改造成线程安全的模式。
4、单例模式的优点
由于单例模式只生成一个实例,减少了系统性能开销。
常见的单例模式应用:
- Windows的Task Manager (任务管理器)就是很典型的单例模式
- Windows的Recycle Bin (回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
- Application 也是单例的典型应用
- 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
代码块
代码块(或初始化块)的作用:
- 对Java类或对象进行初始化
- 代码块(或初始化块)的分类:
- 一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block)
- 没有使用static修饰的,为非静态代码块。
1、静态代码块
在代码块的前面加static,就是静态代码块。
(1)静态代码块的格式
【修饰符】 class 类{
static{
静态代码块
}
}
(2)静态代码块的特点:
- 可以有输出语句。
- 可以对类的属性、类的声明进行初始化操作。
- 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
- 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
- 静态代码块的执行要先于非静态代码块。
- 静态代码块随着类的加载而加载--->只执行一次。
2、非静态代码块
(1)格式:
【修饰符】 class 类{
{
非静态代码块
}
【修饰符】 构造器名(){
// 实例初始化代码
}
【修饰符】 构造器名(参数列表){
// 实例初始化代码
}
}
(2)意义:如果多个构造器中存在公共的代码,且公共代码先于构造器中其他代码执行,则将这些公共代码提取放入代码块中,减少冗余代码。
非静态代码块的执行特点
- 可以有输出语句。
- 可以对类的属性、类的声明进行初始化操作。
- 除了调用非静态的结构外,还可以调用静态的变量或方法。
- 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
- 随着对象的创建而执行,当前类中每创建一个实例,则执行一次非静态代码块。
举例:
public class Block{
public static void main(String[] args) {
//随着类的创建,先行执行静态代码块中的内容。
Person p1 = new Person();//随着对象的创建,调用非静态代码块中的内容
p1.eat();//根据对象调方法。
}
}
class Person{
String name;
int age;
public void eat(){
System.out.println("People need eat.");
}
public static void useComputer(){
System.out.println("I'm so despair.");
}
public Person(){}//空参构造器
{
System.out.println("not static.");
}
static{
System.out.println("static.");
useComputer();
}//静态代码块调用静态结构。
}
原文地址:https://blog.csdn.net/2401_88237139/article/details/143976955
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!