天天看點

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;

}

}