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 程序的意义
程序中虽然声明了3个Singleton对象,但是实际上所有的对象都只使用instance引用,也就是说,此时不管外面如何使用,最终结果也只是有一个实例化对象存在,如图:
在设计模式中将这样的设计称为单例设计模式,即无论程序怎样运行,Singleton类永远只会有一个实例化对象存在。