天天看点

static 与私有构造函数

 java中static是一个很有用的方法。

  首先我们来看一个例子:

[java]  view plain copy

  1. package com.test.dao;  
  2. public class Test {  
  3.     private static int i = 0;  
  4.     private Test() {      // *************************  1  
  5.     }  
  6.     static {  
  7.         System.out.println(i++);  
  8.     }  
  9.     public static int getI() {  
  10.         return i;  
  11.     }  
  12. }   

[java]  view plain copy

  1. package com.test.dao;  
  2. public class Rua implements Runnable {  
  3.     public void run() {  
  4.         System.out.println("RUN: " + Test.getI());  
  5.     }  
  6.     public static void main(String args[])  
  7.     {  
  8.         Thread r1=new Thread(new Rua());  
  9.         Thread r2=new Thread(new Rua());  
  10.         Thread r3=new Thread(new Rua());  
  11.         r1.start();  
  12.         r2.start();  
  13.         r3.start();  
  14.     }  
  15. }  

首先我们来分析Test这个类,这个类中,有一个私有的构造函数,并且有一个static 的方法,在Rua这个类中,到底会有什么样的打印结果?

这个是得到的结果:

static 与私有构造函数

为了更好的说明这一点,继续看下面的两个类:

[java]  view plain copy

  1. public class Test {  
  2.     private static int i = 0;  
  3.     private Test() {   
  4.     }  
  5.     static {  
  6.         System.out.println(i++);  
  7.     }  
  8.     public static int getI() {  
  9.         return i;  
  10.     }  
  11. }  

[java]  view plain copy

  1. package com.test.dao;  
  2. public class Rua implements Runnable {  
  3.     public void run() {  
  4.         System.out.println("RUN: " + Test.getI());  
  5.     }  
  6.     public static void main(String args[])  
  7.     {     
  8.     System.out.println(Test.getI()==Test.getI());  
  9.     }  
  10. }  

打印出的内容为:

static 与私有构造函数

这说明两次所得到的实例是相同的。即单例模式。

所以,在这里不难看出,在static方法内,只运行了一次,并且形成了三个单例,每个单例之间都相互不影响,在Test类中,分别构造了三个不同的实例,这三个实例间相互不会影响。

这里还有一个问题,注意看注释1,这里没有使用共有构造函数,而是使用了私有构造函数,那么如果在这里使用了共有构造函数会有什么影响呢?首先,使用自由构造函数,这个类不可以初始化,即不可以被new出来,如果没有显示的声明构造函数,那么系统会为默认的使用该类的共有构造函数,因此在这里,既然需要使用到单例,那么在这不可避免的就需要使用到私有构造函数,因为,如果使用了共有构造函数,那么可能造成的影响:该类可以被new出来,这样的话,就不能被保证该实例会被这样而使用。

这里还有一点可能会发生疑问的就是,如果构造函数和static同时存在的时候,系统到底先执行哪一个呢?

系统首先会运行static内部的内容。

这里能够引出的问题:大多数人应该看过hibernate的源码,在这里贴一段过来

[java]  view plain copy

  1. public class HibernateSessionFactory {  
  2.     private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";  
  3.     private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();  
  4.     private  static Configuration configuration = new Configuration();      
  5.     private static org.hibernate.SessionFactory sessionFactory;  
  6.     private static String configFile = CONFIG_FILE_LOCATION;  
  7.     static {  
  8.         try {  
  9.             configuration.configure(configFile);  
  10.             sessionFactory = configuration.buildSessionFactory();  
  11.         } catch (Exception e) {  
  12.             System.err  
  13.                     .println("%%%% Error Creating SessionFactory %%%%");  
  14.             e.printStackTrace();  
  15.         }  
  16.     }  
  17.     private HibernateSessionFactory() {  
  18.     }  
  19.     public static Session getSession() throws HibernateException {  
  20.         Session session = (Session) threadLocal.get();  
  21.         if (session == null || !session.isOpen()) {  
  22.             if (sessionFactory == null) {  
  23.                 rebuildSessionFactory();  
  24.             }  
  25.             session = (sessionFactory != null) ? sessionFactory.openSession()  
  26.                     : null;  
  27.             threadLocal.set(session);  
  28.         }  
  29.         return session;  
  30.     }  

在这里,我们便可以看出点hibernate对于数据库连接的眉目了

下面看看Static在hibernate中的一个应用。

package com.nvidia.hibernate;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

public class HibernateUtils {

//成员变量的创建,

private static SessionFactory factory;

//只装载一次变量的写法

static {

try {

Configuration cfg = new Configuration().configure();

factory = cfg.buildSessionFactory();

} catch(Exception e){

e.printStackTrace();

}

}

public Session getSession(){

return factory.openSession();

}

public void closeSession(Session session){

if(session != null)

if(session.isOpen())

session.close();

}

public static SessionFactory getSessionFactory(){

return factory;

}

}