Java中静态变量的适用场景

本文介绍Java中静态变量的使用场景,特别是在节省内存和共享资源方面的作用。通过示例展示如何利用静态变量创建一周各天的名称,从而提高程序效率。

Java中静态变量的适用场景

Java类中的静态变量在程序运行期间,其内存空间对所有该类的对象实例而言是共享的,有些时候可以认为是全局变量。因此在某些时候为了节省系统内存开销、共享资源,可以将类中的一些变量声明为静态变量,通过下面的例子,你可以发现合理应用静态变量带来的好处:

  Java代码

  public class WeekA{

  static class Data {

  private int week;

  private String name;

  Data(int i, String s) {

  week= i;

  name = s;

  }

  }

  Data weeks[] = {

  new Data(1, "Monday"), new Data(2, "Tuesay"), new Data(3, "Wednesday"), new Data(4, "Thursday"), new Data(5, "Friday"), new Data(6, "Saturday"), new Data(7, "Sunday")

  };

  public static void main(String args[]) {

  final int N = 10000;

  WeekA weekinstance;

  for (int i = 1; i <= N; i++){

  weekinstance = new WeekA ();

  }

  }

  } public class WeekA{

  static class Data {

  private int week;

  private String name;

  Data(int i, String s) {

  week= i;

  name = s;

  }

import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.htmlparser.RemarkNode; import org.htmlparser.StringNode; import org.htmlparser.Node; import org.htmlparser.tags.*; import org.htmlparser.Parser; import org.htmlparser.filters.StringFilter; import org.htmlparser.util.NodeIterator; import org.htmlparser.util.NodeList; import org.htmlparser.util.ParserException; import java.util.Queue; import java.util.LinkedList;

  public class Spider implements Runnable {

  boolean search_key_words = false;

  int count = 0;

  int limitsite = 10;

  int countsite = 1;

  String keyword = "中国";//搜索关键字

  Parser parser = new Parser();

  // List linklist = new ArrayList();

  String startsite = "";//搜索的其实站点

  SearchResultBean srb;//保存搜索结果

  List resultlist = new ArrayList();//搜索到关键字链接列表

  List searchedsite = new ArrayList();//已经被搜索站点列表

  Queue linklist = new LinkedList();//需解析的链接列表

  HashMap<String, ArrayList<String>> disallowListCache = new HashMap<String, ArrayList<String>>();

  public Spider(String keyword, String startsite) { this.keyword = keyword; this.startsite = startsite; linklist.add(startsite);

  srb = new SearchResultBean();

  }

  public void run() {

  // TODO Auto-generated method stub

  search(linklist);

  }

  public void search(Queue queue) {

  String url = "";

  while(!queue.isEmpty()){ url = queue.peek().toString();//查找列队

  try {

  if (!isSearched(searchedsite, url)) {

  if (isRobotAllowed(new URL(url)))//检查该链接是否被允许搜索

  processHtml(url);

  else

  System.out.println("this page is disallowed to search");

  }

  } catch (Exception ex) {

  }

  queue.remove();

  }

  }

  /**

  *解析HTML

  * @param url

  * @throws ParserException

  * @throws Exception

  */

  public void processHtml(String url) throws ParserException, Exception { searchedsite.add(url);

  count = 0;

  System.out.println("searching ... :" + url); parser.setURL(url); parser.setEncoding("GBK"); URLConnection uc = parser.getConnection(); uc.connect(); //uc.getLastModified(); NodeIterator nit = parser.elements();

  while (nit.hasMoreNodes()) { Node node = nit.nextNode();

  parserNode(node);

  } 来源:考试大-Java认证考试 

  }

  Data weeks[] = {

  new Data(1, "Monday"), new Data(2, "Tuesay"), new Data(3, "Wednesday"), new Data(4, "Thursday"), new Data(5, "Friday"), new Data(6, "Saturday"), new Data(7, "Sunday")

  };

  public static void main(String args[]) {

  final int N = 10000;

  WeekA weekinstance;

  for (int i = 1; i <= N; i++){

  weekinstance = new WeekA ();

  }

  }

  }


<think>我们正在讨论Java中的实例变量和静态变量的区别及用法。根据用户的问题和之前的回答,我们需要更详细地解释这两个概念,并引用提供的参考资料。 关键点: 1. 定义:实例变量属于对象,静态变量属于类。 2. 内存分配:实例变量每个对象独立,静态变量所有对象共享。 3. 生命周期:实例变量随对象创建而存在,对象回收而销毁;静态变量随类加载而存在,程序结束才销毁。 4. 访问方式:实例变量必须通过对象访问;静态变量推荐通过类名访问(也可通过对象但不推荐)。 5. 初始化:实例变量在创建对象时初始化;静态变量在类加载时初始化。 我们将结合引用内容,给出代码示例,并总结区别表格,最后生成相关问题。</think>### Java 实例变量与静态变量的区别及用法详解 #### 一、核心概念对比 | 特性 | 实例变量 (对象变量) | 静态变量 (类变量) | |--------------|----------------------------------------|---------------------------------------| | **所属主体** | 对象实例 | 类本身 | | **内存分配** | 每个对象独立副本(堆内存) | 全局唯一副本(方法区) | | **生命周期** | 对象创建时产生,对象销毁时释放 | 类加载时产生,程序结束时释放[^3] | | **共享性** | 对象私有 | 类所有实例共享 | | **访问方式** | `对象名.变量名` | `类名.变量名`(推荐) | | **初始化** | 构造方法中初始化 | 类加载时自动初始化 | | **线程安全** | 对象内部隔离,相对安全 | 需额外同步控制(如`synchronized`) | > **本质区别**:实例变量描述**对象状态**(如学生的姓名),静态变量描述**类级别状态**(如学生总数)[^2][^3] #### 二、代码示例解析 ```java public class BankAccount { // 实例变量(每个账户独立) private String accountId; private double balance; // 静态变量(所有账户共享) public static double interestRate = 0.03; // 年利率 private static int totalAccounts = 0; // 账户总数 public BankAccount(String id, double initBalance) { this.accountId = id; this.balance = initBalance; totalAccounts++; // 创建新账户时更新共享计数器 } public static void main(String[] args) { // 访问静态变量(无需创建对象) System.out.println("当前利率:" + BankAccount.interestRate); BankAccount acc1 = new BankAccount("001", 5000); BankAccount acc2 = new BankAccount("002", 10000); // 访问实例变量(需通过对象) System.out.println(acc1.accountId + "余额:" + acc1.balance); // 001余额:5000.0 // 访问静态变量(通过类名) System.out.println("总账户数:" + BankAccount.totalAccounts); // 总账户数:2 // 不推荐方式:通过对象访问静态变量(编译器警告) System.out.println(acc1.interestRate); // 0.03 } } ``` #### 三、关键区别详解 1. **内存模型差异** - 实例变量:每`new`一个对象,在堆内存创建独立副本 - 静态变量:类加载时在方法区创建**唯一副本**,所有对象共享[^3] ```mermaid graph LR A[类加载] --> B[方法区-静态变量] C[new对象1] --> D[堆内存-实例变量副本1] E[new对象2] --> F[堆内存-实例变量副本2] D & F --> B ``` 2. **访问限制** - 实例变量:必须通过对象访问(`obj.var`) - 静态变量:推荐通过类名访问(`Class.var`),通过对象访问会引发编译器警告[^4] 3. **初始化时机** - 实例变量:在构造方法执行时初始化 - 静态变量:在**类加载阶段**初始化(早于对象创建)[^3] ```java public class InitDemo { int instanceVar = init("实例变量"); // 每次new时执行 static int staticVar = init("静态变量"); // 类加载时执行一次 static int init(String type) { System.out.println("初始化" + type); return 0; } } /* 输出: 初始化静态变量 初始化实例变量 初始化实例变量 */ ``` #### 四、使用场景指南 | **变量类型** | **适用场景** | **注意事项** | |--------------|---------------------------------------|---------------------------------------| | 实例变量 | 对象特有属性(账户ID、余额) | 线程安全需对象级同步 | | 静态变量 | 共享数据(全局配置、计数器、常量) | 1. 多线程需同步控制<br>2. 避免过度使用导致内存泄漏 | > **最佳实践**: > - 常量声明:`public static final double PI = 3.14159;` > - 对象计数器:`private static int count = 0;` > - 线程安全示例: > ```java > public class Counter { > private static int count = 0; > // 静态方法添加同步锁 > public static synchronized void increment() { > count++; > } > } > ``` #### 五、常见误区 1. **通过对象修改静态变量** ```java BankAccount acc = new BankAccount("003", 2000); acc.interestRate = 0.04; // 实际修改的是Class.interestRate ``` 所有对象访问的`interestRate`都会改变,易引发逻辑错误[^4] 2. **静态方法访问实例变量** ```java public static void printBalance() { System.out.println(balance); // 编译错误!无法访问非静态变量 } ``` 静态方法只能访问静态变量,因其实例变量可能尚未创建。 --- ### 相关问题 1. 为什么在多线程环境下修改静态变量需要同步控制? 2. 静态变量是否会导致内存泄漏?如何预防? 3. 如何在Java中实现线程安全的单例模式(涉及静态变量)? 4. 静态常量(`static final`)与普通静态变量有何区别? 5. 类加载过程中静态变量的初始化顺序是怎样的?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值