static 与私有构造函数

来源:互联网 发布:seo文章编辑 编辑:程序博客网 时间:2024/05/22 10:49

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

  首先我们来看一个例子:

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

 

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

这个是得到的结果:

 

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

[java] view plaincopy
  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 plaincopy
  1. package com.test.dao;  
  2. public class Rua implements Runnable {  
  3.     public void run() {  
  4.         System.out.println("RUN: " + Test.getI());  
  5.     }  
  6.       
  7.     public static void main(String args[])  
  8.     {     
  9.     System.out.println(Test.getI()==Test.getI());  
  10.     }  
  11. }  

打印出的内容为:

 

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

 

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

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

 

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

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

 

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

[java] view plaincopy
  1. public class HibernateSessionFactory {  
  2.     /**  
  3.      * Location of hibernate.cfg.xml file. 
  4.      * Location should be on the classpath as Hibernate uses   
  5.      * #resourceAsStream style lookup for its configuration file.  
  6.      * The default classpath location of the hibernate config file is  
  7.      * in the default package. Use #setConfigFile() to update  
  8.      * the location of the configuration file for the current session.    
  9.      */  
  10.     private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";  
  11.     private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();  
  12.     private  static Configuration configuration = new Configuration();      
  13.     private static org.hibernate.SessionFactory sessionFactory;  
  14.     private static String configFile = CONFIG_FILE_LOCATION;  
  15.     static {  
  16.         try {  
  17.             configuration.configure(configFile);  
  18.             sessionFactory = configuration.buildSessionFactory();  
  19.         } catch (Exception e) {  
  20.             System.err  
  21.                     .println("%%%% Error Creating SessionFactory %%%%");  
  22.             e.printStackTrace();  
  23.         }  
  24.     }  
  25.     private HibernateSessionFactory() {  
  26.     }  
  27.       
  28.     /** 
  29.      * Returns the ThreadLocal Session instance.  Lazy initialize 
  30.      * the <code>SessionFactory</code> if needed. 
  31.      * 
  32.      *  @return Session 
  33.      *  @throws HibernateException 
  34.      */  
  35.     public static Session getSession() throws HibernateException {  
  36.         Session session = (Session) threadLocal.get();  
  37.         if (session == null || !session.isOpen()) {  
  38.             if (sessionFactory == null) {  
  39.                 rebuildSessionFactory();  
  40.             }  
  41.             session = (sessionFactory != null) ? sessionFactory.openSession()  
  42.                     : null;  
  43.             threadLocal.set(session);  
  44.         }  
  45.         return session;  
  46.     }  

在这里,我们便可以看出点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;
}
}