1.1 代码块

所谓的代码块是指使用“{}”括起来的一段代码,根据位置的不同,代码块可以分为普通代码块、构造块、静态代码块、同步代码块4种。

1.1.1 普通代码块

class CodeDemo01{

public static void main(String[] args) {

{

int x = 30;

System.out.println("普通代码块-->x = " + x);

}

int x = 100;

System.out.print("代码块之外-->x = " + x);

}

}

运行结果:

普通代码块-->x = 30

代码块之外-->x = 100

1.1.2 构造块

class Demo07{

{

System.out.println("1、构造块");

}

public Demo07(){

System.out.println("2、构造方法");

}

}

class CodeDemo02{

public static void main(String[] args) {

new Demo07();

new Demo07();

new Demo07();

}

}

运行结果:

1、构造块

2、构造方法

1、构造块

2、构造方法

1、构造块

2、构造方法

构造块优先于构造方法执行,而且每次实例化对象时都会执行构造块中的代码,会执行多次。

1.1.3 静态代码块

class Demo08{

{

System.out.println("1、构造块");

}

static{

System.out.println("0、定义静态代码块");

}

public Demo08(){

System.out.println("2、构造方法");

}

}

class CodeDemo03{

public static void main(String[] args) {

new Demo08();

new Demo08();

new Demo08();

}

}

运行结果:

0、定义静态代码块

1、构造块

2、构造方法

1、构造块

2、构造方法

1、构造块

2、构造方法

静态代码块优先于主方法执行,而在类中定义的静态代码块会优先于构造方法执行,而且不管有多少个对象产生,静态代码块只执行一次。

1.2 构造方法私有化

1.2.1 问题的引出

类的封装性不只体现在对属性的封装上,实际上方法也是可以封装的,当然,在方法封装中也包含了对构造方法的封装。

构造方法的封装:

class Singleton{

private Singleton(){

}

public void print(){

System.out.println("Hello World");

}

}

一个类要想使用,则必须有实例化对象的产生,而且现在要是想调用Singleton类中的print()方法,则一定要首先产生Singleton的实例化对象,但是由于此时构造方法被私有化了,所以直接实例化Singleton类会出现错误。如下:

Exception in thread "main" java.lang.Error: Unresolved  compilation problem: 

The constructor Singleton() is not visible

at  com.my.javaClass.Singleton02.main(Day05.java:1039)

封装是指一切都外部不可见,那么就意味着在外部根本就无法调用被封装的构造方法,既然外部不能调用,那么在内部呢?

class Singleton03{

private Singleton03(){

}

Singleton03 instance = new Singleton03();

public void print(){

System.out.println("Hello World");

}

}

在类内部实例化并不会产生任何的问题。此时将内部的instance对象传递到类的外部去,这样外部就可以通过instance来实例化Singleton对象。

1.2.2 问题的解决

学习static时曾讲过,是他提出类型的属性可以由类名直接调用,所以此时将instance属性声明为static类型,这样就可以通过类名直接调用。

class Singleton03{

private Singleton03(){

}

static Singleton03 instance = new Singleton03();

public void print(){

System.out.println("Hello World");

}

}

class SingletonDemo03{

public static void main(String[] args) {

Singleton03 s1 = Singleton03.instance;

s1.print();

}

}

运行结果:

Hello World

陈功的取得了Singleton的实例化对象并调用了其中的print()方法。但是,类中的属性必须封装,所以此处应该将instance属性进行封装,而封装之后必须通过方法取得,但因为instance属性属于静态属性,所以此处必须声明一个静态方法,这样就可以被类名称直接调用。

class Singleton04{

private Singleton04(){

}

private static Singleton04 instance = new Singleton04();

public static Singleton04 getInstance(){

return instance;

}

public void print(){

System.out.println("Hello World");

}

}

class SingletonDemo04{

public static void main(String[] args) {

Singleton04 s1 = Singleton04.getInstance();

Singleton04 s2 = Singleton04.getInstance();

Singleton04 s3 = Singleton04.getInstance();

s1.print();

s2.print();

s3.print();

}

}

运行结果:

Hello World

Hello World

Hello World

1.2.3 程序的意义

程序中虽然声明了3Singleton对象,但是实际上所有的对象都只使用instance引用,也就是说,此时不管外面如何使用,最终结果也只是有一个实例化对象存在,如图:

 

在设计模式中将这样的设计称为单例设计模式,即无论程序怎样运行,Singleton类永远只会有一个实例化对象存在。