对static关键字的一点测试

本文通过具体的数据库连接示例,对比了使用StaticBlock与StaticMethod进行数据库连接的效率。结果显示,StaticBlock方法明显优于StaticMethod方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在翻阅《JDK6学习笔记》时,看到static关键字用法,虽然很早就知道大概,但自己没有动手试过,遂决定试试到底static关键字能否带来好处。举个例子,一般情况下,可能在连接数据库时,首先会在自己的类中做一些初始化动作,那么我们假设利用static block来初始数据库的连接与一般数据库连接有什么不同呢,写了如下粗略测试代码:

package cn.xbmu.lib.jfly.test;

import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 测试Static Block用法,在Static Block中初始化一个数据库连接
 * @author JFly
 */
public class TestStaticBlock {

    private static Connection conn = null;
    static String CLASSFORNAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    static String CONN_STR = "jdbc:sqlserver://localhost:1433;databaseName=oblog";
    static String DB_USER = "sa";
    static String DB_PWD = "";
    private static ResultSet rs = null;


    static {
        try {
            Class.forName(CLASSFORNAME);
            conn = DriverManager.getConnection(CONN_STR, DB_USER, DB_PWD);
            System.out.println("数据库连接已建立!");
        } catch (SQLException ex) {
            Logger.getLogger(TestStaticBlock.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(TestStaticBlock.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public String getRecord(Connection aConn, int id) {

        try {
            rs = aConn.prepareStatement("select * from oblog_user where userid = " + "'" + id + "'").executeQuery();
            if (rs.next()) {
                System.out.println("rs=" + rs);
                System.out.println("username=" + rs.getString("username"));
                return rs.getString("username");
            }
        } catch (SQLException ex) {
            Logger.getLogger(TestStaticBlock.class.getName()).log(Level.SEVERE, null, ex);
        } 
        
        return "没有记录";
    }

    public static Connection getConn() throws SQLException {
        if (conn != null) {
            return conn;
        }
        return DriverManager.getConnection(CONN_STR, DB_USER, DB_PWD);
    }

    public static void closeConn() throws SQLException {
        if(rs != null) {
            rs.close();
        }
        if(conn != null) {
            conn.close();
        }
    }

    public static void main(String[] args) throws SQLException {
        long beginTime = System.currentTimeMillis();
        TestStaticBlock tsb = new TestStaticBlock();
        //TestStaticBlock.conn = null;
        System.out.println("conn1 = " + TestStaticBlock.conn);
        System.out.println("conn2 = " + TestStaticBlock.getConn());
        System.out.println("username = " + tsb.getRecord(getConn(), 3));
        long endTime = System.currentTimeMillis();

        TestStaticBlock tsb_1 = new TestStaticBlock();
        System.out.println("conn1 = " + TestStaticBlock.conn);
        System.out.println("username = " + tsb_1.getRecord(getConn(), 4));
        
        closeConn();
        System.out.println("执行时间:" + (endTime - beginTime));
    }
}

 

输出执行时间大致为63,而如果静态方法呢,代码如下:

package cn.xbmu.lib.jfly.test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 测试static方法
 * @author JFly
 */
public class TestStaticMethod {

    public static void getUser(int id) {
        String CLASSFORNAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        String CONN_STR = "jdbc:sqlserver://localhost:1433;databaseName=oblog";
        String DB_USER = "sa";
        String DB_PWD = "";
        Connection conn = null;

        long beginTime = System.currentTimeMillis();
        try {
            Class.forName(CLASSFORNAME);
            conn = DriverManager.getConnection(CONN_STR, DB_USER, DB_PWD);

            System.out.println("数据库连接已建立!");

            ResultSet rs = null;
            try {

                rs = conn.prepareStatement("select * from oblog_user where userid = " + "'" + 3 + "'").executeQuery();
                if (rs.next()) {
                    System.out.println("username = " + rs.getString("username"));
                }
            } catch (SQLException ex) {
                Logger.getLogger(TestStaticBlock.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                if (rs != null) {
                    rs.close();
                }
                if (conn != null) {
                    conn.close();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        long endTime = System.currentTimeMillis();
        System.out.println("执行时间:" + (endTime - beginTime));
    }

    public static void main(String[] args) {
        TestStaticMethod.getUser(3);
    }
}

 

程序执行时间大致为297,可见static block带来的效率要比static method高很多。

<think>好的,用户想了解static关键字在编程中的作用和用法。首先,我需要回忆一下static在不同编程语言中的常见用途。记得在C/C++中,static可以用于控制变量和函数的作用域和生命周期,比如在函数内部声明静态变量,使其在函数调用之间保持值不变。另外,在全局变量或函数前使用static可以限制它们仅在当前文件内可见,这有助于模块化设计,避免命名冲突。然后,在面向对象的语言如Java或C#中,static用于定义类级别的成员,这些成员属于类本身而不是实例,可以通过类名直接访问。比如静态变量被所有实例共享,静态方法不能访问非静态成员。这部分需要举例说明,帮助用户理解。 接下来,用户提供的引用内容提到嵌入式系统中static的重要性,特别是在模块化编程和避免命名冲突方面。比如Linux内核模块编程中,使用static声明函数和全局变量,限制作用域,再通过EXPORT导出需要共享的部分。这一点需要强调static在大型项目中的协作优势。 还要注意不同语言之间的差异,比如在C++中,静态成员变量需要在类外初始化,而Java则不需要。同时,要指出static的内存管理,比如静态变量在程序的生命周期内存在,可能导致内存占用,需谨慎使用。 用户可能的问题包括性能影响、滥用static的后果、不同语言中的区别等。需要确保回答覆盖这些潜在疑问,并给出实际例子,比如计数器或单例模式的应用,增强实用性。 最后,检查是否有遗漏点,如静态函数在C中的隐藏作用,或者静态局部变量在递归中的行为。确保结构清晰,分点阐述,每个作用都配以代码示例,帮助用户直观理解。同时,引用提供的资料,特别是关于模块化和移植性的部分,强化答案的可信度。</think>### static关键字的作用与用法解析 static关键字在编程中具有**控制变量/函数作用域**和**延长生命周期**两大核心功能,具体作用因编程语言和应用场景而异。以下是分点解析: --- #### 一、C/C++中的static关键字 1. **静态局部变量** - **作用**:在函数内部声明时,变量生命周期延长至程序结束,但作用域仍限于函数内。 - **用法**:用于保留函数调用间的状态,如计数器。 ```c void count() { static int num = 0; // 仅初始化一次 num++; printf("%d", num); } ``` - **示例**:第一次调用`count()`输出1,第二次输出2[^4]。 2. **静态全局变量/函数** - **作用**:限制全局变量或函数仅在**当前文件**内可见,避免多文件编译时的命名冲突。 - **用法**:在模块化开发中隐藏内部实现。 ```c static int internal_var; // 仅本文件可见 static void helper() { ... } // 仅本文件调用 ``` 3. **静态成员(C++)** - **类静态变量**:所有实例共享同一变量,需在类外初始化。 ```cpp class MyClass { public: static int count; // 声明 }; int MyClass::count = 0; // 类外初始化 ``` - **静态成员函数**:只能访问静态成员,通过类名调用。 ```cpp class MyClass { public: static void print() { cout << count; } }; ``` --- #### 二、Java/C#中的static关键字 1. **静态变量** - **作用**:所有实例共享同一变量,常用于全局配置或计数器。 ```java public class Counter { static int count = 0; // 所有实例共享 } ``` 2. **静态方法** - **作用**:无需实例化即可调用,但只能访问静态成员。 ```java public class MathUtils { public static int add(int a, int b) { return a + b; } } // 调用:MathUtils.add(2,3); ``` 3. **静态代码块(Java)** - **作用**:类加载时执行初始化操作。 ```java public class Database { static { // 加载数据库驱动 } } ``` --- #### 三、关键应用场景 1. **模块化设计** - 通过`static`隐藏内部函数/变量,提升代码封装性(如Linux内核模块)[^2][^4]。 2. **性能优化** - 静态变量避免重复初始化,减少内存分配开销。 3. **单例模式** - 结合`static`实现全局唯一实例。 ```java public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } } ``` --- #### 四、注意事项 1. **内存管理**:静态变量生命周期与程序相同,滥用可能导致内存泄漏。 2. **线程安全**:多线程环境下需对静态变量加锁(如Java的`synchronized`)。 3. **测试困难**:静态方法可能引入隐藏依赖,降低代码可测试性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值