2010-02-10 93 views
3

在C#中,我能夠創造這樣一個類:然後在任何地方我可以命名空間不初始化用這種方式如何在Java中聲明一個全局靜態類?

static class clsDBUtils 
{ 
     public static SQLiteCommand cmd; 
     public static SQLiteConnection conn; 
     public static String databaseFilePath; 

     public static bool getConnection() 
     { 
     } 
} 

clsDBUtils.getConnection(); 

怎麼可以這樣改寫爲Java?

我不想使用:

clsDBUtils sqlutil= new clsDBUtils(); 

回答

9

方式基本相同,只是做一個(正常)final類的私人構造器(防止能夠做new)和只添加靜態成員。

public final class clsDBUtils { 
    public static SQLiteCommand cmd; 
    public static SQLiteConnection conn; 
    public static String databaseFilePath; 

    public static bool getConnection() { 
    } 

    private clsDBUtils() {} 
} 
+0

爲什麼我需要'final'修飾符? – Pentium10

+3

@ Pentium10:防止類被擴展;如果它可以被擴展,那麼它可以被實例化。 –

1

它的代碼幾乎是完全一樣的(同樣的概念,稍微不同的語法)

public class ClsDBUtils 
{ 
    public static SQLiteCommand cmd; 
    public static SQLiteConnection conn; 
    public static String databaseFilePath; 

    public static boolean getConnection() 
    { 
    } 
} 

// somewhere else 
ClsDBUtils.getConnection(); 
0

只需要聲明一個公共類,並使用「靜態」修飾符在你的方法和字段。如果您不希望它被實例化,請使用'public final class'。或者,您可以使用單例類。

0

希望實現Singleton模式:http://en.wikipedia.org/wiki/Singleton_pattern

public class clsDBUtils { 
    private static final clsDBUtils INSTANCE = new clsDBUtils(); 

    // Private constructor prevents instantiation from other classes 
    private clsDBUtils() {} 

    public static clsDBUtils getInstance() { 
     return INSTANCE; 
    } 

    public SQLiteCommand cmd; 
    public SQLiteConnection conn; 
    public String databaseFilePath; 

    public bool getConnection() 
    { 
    } 
} 

然後可以使用以下語法類:

clsDBUtils.getInstance().getConnection(); 
+0

否否否。你做錯了。使用枚舉而不是類或記住重寫readResolve。請參閱_Effective Java_的項目77。 – KitsuneYMG

+0

我不關注。海報沒有要求該類是可串行化的,所以它不需要readResolve()。上面的模式是一個簡單的Singleton實現 - 請參閱設計模式:可重複使用面向對象軟件的元素 – seanhodges

5

除了特定問題/問題,這是壞練習宣佈昂貴的和外部的資源,如Connection,StatementResultSet作爲一個實例變量,更不用說作爲static變量。這些資源沒有無窮無盡的生命週期,當DB決定超時連接時,應用程序可能會中斷,因爲它在使用後沒有被釋放回數據庫。

我無法想象它在C#中的做法是不同的(它也是應用程序中的一個bug),但是正常的JDBC成語是您在儘可能短的範圍內獲取並關閉它,同樣的方法塊。例如。

public Entity find(Long id) throws SQLException { 
    Connection connection = null; 
    PreparedStatement statement = null; 
    ResultSet resultSet = null; 
    Entity entity = null; 

    try { 
     connection = database.getConnection(); 
     statement = connection.prepareStatement(SQL_FIND); 
     statement.setLong(1, id); 
     resultSet = statement.executeQuery(); 

     if (resultSet.next()) { 
      entity = new Entity(); 
      entity.setProperty(resultSet.getObject("columnname")); 
      // etc.. 
     } 
    } finally { 
     // Always free resources in reversed order. 
     if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {} 
     if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {} 
     if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {} 
    } 

    return entity; 
} 

database.getConnection()可以但是在技術上完全可以做靜態這樣的:

public final class Database { 
    static { 
     try { 
      Class.forName("com.example.jdbc.Driver"); 
     } catch (ClassNotFoundException e) { 
      throw new ExceptionInInitializerError(e); 
     } 
    } 

    private Database() { 
     // No need to instantiate this class. 
    } 

    public static Connection getConnection() { 
     DriverManager.getConnection("jdbc:example://localhost/dbname", "user", "pass"); 
    } 
} 

,這樣你可以使用它作爲

connection = Database.getConnection(); 

(你還真需要關閉的finally block after use!)

但是,這使得t他的連線源也真的是static。您不能再利用多態性和/或繼承來切換連接源(如連接池)(以獲得更好的性能)。爲了獲得更多想法/見解,您可能會發現this article有用

+0

的第127頁,每次連接和斷開連接,應用程序會更慢嗎? – Pentium10

+0

這就是連接池的用途,這也是我在答案中暗示它的原因。我可以推薦抓住c3p0:http://sourceforge.net/projects/c3p0/ – BalusC

+0

我會在Android上使用。我被告知,在移動設備上最好在啓動時打開連接,當應用程序存在時關閉,而在桌面應用程序中,建議在完成該窗口後打開並關閉連接。在移動平臺上,開放的流程可能需要很多資源,而且這麼做可能會很痛苦。我明白,在執行查詢之前,我們必須確保存在活動連接(操作系統可以關閉它) – Pentium10