构造方法的私有化
一个方法可根据实际需要,将其设置为不同的访问权限——public(公有访问)、private(私有访问)或默认访问(即方法前没有修饰符)。
同样,构造方法也有public与private之分。如果构造方法被设为private,那么其他类中就无法调用该构造方法。 换句话说,在本类之外,就不能通过new关键字调用该构造方法创建该类的实例化对象,构造方法被声明为private类型则只能在类内部访问。。
先来看一个例子:
public class Demo {
private Demo() {} // 私有构造
public static void main(String[] args) {
Demo dd = new Demo(); // 可以在本类中实例化
}
}
class Test {
Demo d = new Demo(); // 错误,在本类之外,不能通过new关键字调用私有构造方法创建该类的实例化对象。
}
再来看一个例子:
package com.xy.test3;
class Singleton {
static Singleton instance = new Singleton(); // 实例化对象
// 此时的类中不会再生成无参的什么都不做的构造
private Singleton() {}
public void print() {
System.out.println("Hello World!");
}
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton instance = null; // 声明对象
instance = Singleton.instance; // 实例化对象
instance.print();
}
}
【结果】
类之中的所有属性只有在调用构造方法实例化对象之后才会分配空间。
那么现在外部无法调用Singleton类的构造方法,所以依靠外部是不可能的,那么就必须从内部的instance定义上想办法,有没有一种方法可以让Singleton在没有实例化对象的时候就去操作instance呢?自然可以想到使用static定义。
可是针对于类之中所有定义的属性都会有一个明确的要求,必须使用private封装,那么一旦封装之后,如果此时还希望可以在没有实例化对象的时候取得instance属性,就必须利用static方法返回。 如下:
package com.xy.test3;
class Singleton {
private static Singleton instance = new Singleton(); // 实例化对象
// 此时的类中不会再生成无参的什么都不做的构造
private Singleton() {}
public void print() {
System.out.println("Hello World!");
}
public static Singleton getInstance() { // 利用静态方法返回对象实例
return instance;
}
}
public class SingletonPattern {
public static void main(String[] args) {
Singleton instance = null; // 声明对象
instance = Singleton.getInstance(); // 实例化对象
instance.print();
}
}
【结果】
如果要想产生类的实例化对象,那么一定要调用构造方法,如果把一个类的构造方法卡死了,那么就表示外部无法调用此构造,就意味着外部无法产生实例化对象。
同时在类内部定义的本类实例化对象使用的是static定义,static的特点是在全局数据区之中保存,是一个公共属性,那么这样一来,不管在外部声明了多少个对象,那么实际上只是取得了唯一的一个实例化对象,所以这样的设计在设计模式上讲称为单例设计模式。 Java中的构造方法私有化就是为这种软件设计模式而服务的。
但是以上的代码编写实际上也存在一个问题,既然现在希望表示只有唯一的一个实例化对象,那么为了避免内部的对象会被重复实例化,所以最好加上一个关键字final定义。如下:
public class TestSingleDemo {
public static void main(String[]args) {
/*声明一个Person类的对象
*虽私有化Person类的构造方法,
*但可通过Person类公有接口获得Person实例化对象
*/
Person p; /* 声明一个Person类的对象p,但并未实例化,
* 仅是在栈内存中为对象引用p分配了空间存储,
* p所指向的对象并不存在。
*/
p=Person.getPerson();
System.out.println("姓名:"+p.name);
}
}
class Person
{
String name;
/*
* 在类声明了一个Person类的实例化对象,
* 此对象是在Person类的内部实例化,所以可以调用私有构造方法。
* 此对象被标识为static类型,表示为一静态属性。
* 另外,在声明Person对象的时候还加上了一个final关键字,
* 此关键字表示对象PERSON不能被重新实例化,表示该对象不可更改。
*/
private static final Person PERSON=new Person();
private Person()
{
name="kehr";
}
public static Person getPerson()
{
return PERSON;
}
}
【结果】
【结果分析】
由于Person类构造方法是private,所以如 Person p = new Person () ;已经不再可行了。只能通过“p = Person.getPerson();”来获得实例。
而由于这个实例PERSON是static的,全局共享一个,所以无论在Person类的外部声明多少个对象,使用多少个“p = Person.getPerson();”,最终得到的实例都是同一个。
也就是说,此类只能产生一个实例对象。 这种做法就是上面提到的单态设计模式。
所谓设计模式也就是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。