2010-02-10 39 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