首页 > 学院 > 开发设计 > 正文

通过私有构造方法创建对象

2019-11-17 03:54:00
字体:
来源:转载
供稿:网友
如果你看到标题就已经知道我要写什么内容了,看来你的功力还在我之上;如果你一头雾水,那仔细往下看就对了。

我先写一个单例模式:

view plaincopy to clipboardPRint?
package test.reflect;   
  
public class Singleton {   
    private static Singleton s= null;   
       
    private Singleton() {   
           
    }   
       
    public static Singleton getInstance() {   
        if (s == null) {   
            synchronized (Singleton.class) {   
                if (s == null) {   
                    s = new Singleton();   
                }   
            }   
        }   
        return s;   
    }   
}  
package test.reflect;

public class Singleton {
private static Singleton s= null;

private Singleton() {

}

public static Singleton getInstance() {
if (s == null) {
synchronized (Singleton.class) {
if (s == null) {
s = new Singleton();
}
}
}
return s;
}
}


这个Singleton类是一个单实例模型,它的构造方法是private修饰的,外部类没有办法通过new来创建它的实例,只能通过调用它的静态方法getIntance来获得实例,并且在多处调用都返回一个实例,再也不创建多余的实例。

我们的客户端如下:

view plaincopy to clipboardprint?
Singleton singleton = Singleton.getInstance();   
System.out.println(singleton);   
//singleton = new Singleton();这是行不通的  
Singleton singleton = Singleton.getInstance();
System.out.println(singleton);
//singleton = new Singleton();这是行不通的

打印结果如下:

view plaincopy to clipboardprint?
test.reflect.Singleton@c17164  
test.reflect.Singleton@c17164

但是我们怎样通过private的构造方法创建一个实例呢,答案是反射。

反射式java里重要的一个模块,了解反射可以为我们做很多工作。反射的基本原理就是将一个类的字节码映射成一个可以描述这个类的各种信息的Class对象。

下面我们会在客户端加上一些代码:

view plaincopy to clipboardprint?
Singleton singleton = Singleton.getInstance();   
System.out.println(singleton);   
//singleton = new Singleton();这是行不通的   
  
Class<?> clazz = Singleton.class;   
//Class<?> clazz = Class.forName("test.reflect.Singleton");//这样也行   
Constructor<?>[] constructors = clazz.getDeclaredConstructors();//获得声明的构造器   
Constructor<?> privateConstructor = constructors[0];//Singleton类只有一个构造器   
privateConstructor.setaccessible(true);//设置accessible为true就可以操作它了   
Singleton instance = (Singleton) privateConstructor.newInstance();   
System.out.println(instance);   
           
System.out.println(singleton == instance);  
Singleton singleton = Singleton.getInstance();
System.out.println(singleton);
//singleton = new Singleton();这是行不通的

Class<?> clazz = Singleton.class;
//Class<?> clazz = Class.forName("test.reflect.Singleton");//这样也行
Constructor<?>[] constructors = clazz.getDeclaredConstructors();//获得声明的构造器
Constructor<?> privateConstructor = constructors[0];//Singleton类只有一个构造器
privateConstructor.setAccessible(true);//设置accessible为true就可以操作它了
Singleton instance = (Singleton) privateConstructor.newInstance();
System.out.println(instance);

System.out.println(singleton == instance);

打印结果为:

view plaincopy to clipboardprint?
test.reflect.Singleton@c17164   
test.reflect.Singleton@1fb8ee3   
false  
test.reflect.Singleton@c17164
test.reflect.Singleton@1fb8ee3
false

我们看到了,两次创建的对象是不同的,我们确实通过私有的构造方法创建了一个Singleton类的实例。



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liuhe688/archive/2009/12/31/5110637.aspx
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表