Java之成员变量、全局变量、局部变量的区别

本文详细解析了不同类型的变量在内存中的存储位置及其生命周期,并通过一个具体的开发案例说明了如何正确处理成员变量与局部变量之间的关系,以避免常见的并发问题。

存储区域:

全局变量(全局静态变量)是放在方法区中。

成员变量如果没有实例化那么变量是放在栈中;实例化了对象放在堆中,栈中放的是指向堆中对象的引用地址。

局部变量放在栈中,new的对象放在堆中,8中基本数据类型变量放在栈中,变量所对应的值是放在栈帧中。

生命周期:

全局变量:当类加载的时候,就开始被创建,在类中只有一份; 会跟着类的消失而消失,生存时间叫长。

成员变量:在对象被创建时而存在,当对象被GC回收的同时,他也会消失,生存时间适中。

局部变量:当方法被调用时而存在,当方法调用结束而消失,生存时间短。

作用域:

全局变量:作用整个类中,直接被类调用。

成员变量:作用在整个类中(除静态方法不能使用,静态方法没有隐式的this),被对象调用。

局部变量:作用在一个局部区域,比如说在一个方法中,方法调用。

 

在开发中遇到的问题:

问题:比如说在一个类中定义一个成员变量,在这个类中添加一个for循环,给成员变量赋不同的值,再把值放在队列中。你会发现存在队列的值都是一样的。

解决:在for循环定义一个局部变量并实例化,在把值放进去,这样就会解决值都是一样的问题。

例子:

成员变量:

方法:

public void BfdAiEvent(Object sender, BfdAiEventArgs args){
			
			/**
			 * 'sectionLengthPerChan * channelCount * sectionsCount' tell driver how many samples 
			 *  driver allocate memory for raw data.
			 */
			rawDataBufferLength = configure.sectionLength * configure.channelCount;
			rawDataBufferLength = Math.min(rawDataBufferLength, args.Count);
			if (dataScaled == null || dataScaled.length < rawDataBufferLength) {
					dataScaled = new double[rawDataBufferLength];
					}
			ErrorCode errorCode = wfAiCtrl.GetData(rawDataBufferLength, dataScaled, 0, null, null, null, null);
			
			if(Global.BioFaild(errorCode)){
				ShowMessage("Sorry, there're some errors occred, ErrorCode: " + errorCode.toString());
				return;
			}
			graph.Chart(dataScaled, configure.channelCount, rawDataBufferLength / configure.channelCount, xInc);			
		}
		

这个方法是研华采集卡动态生成数据的方法,就是一个线程一直再跑。

	public void Chart(double[] data, int PlotCount, int DataCountPerPlot, double xIncBySec) {
		System.out.println("=====threadName1===="+ Thread.currentThread().getName());
		if(taskQue.putTask(data) > 5){
			TaskExecute task = new TaskExecute(taskQue);
			task.start();
		}
		Chart(data, PlotCount, DataCountPerPlot, xIncBySec, false);
	}
	public  int putTask(double[] data) {
		try {
			double[] newData = Arrays.copyOf(data, data.length);
			if (taskQueue.offer(newData)) {
				System.out.println("插入任务单队列成功!");
				for (double[] data1 : taskQueue ) {
					System.out.println(Arrays.toString(data1));
				}
			}
		} catch (Exception e) {
			System.out.printf("任务列中插入任务数据异常,",e);
		}
		return taskQueue.size();
	}

重要的一句代码:double[] newData = Arrays.copyOf(data, data.length);解决问题。

 

### Java成员变量局部变量全局变量的关系 #### 成员变量 成员变量属于类的一部分,在整个对象生命周期内都有效。这些变量存储于堆内存中,随着对象的创建而分配空间,并随对象销毁而释放。成员变量可以由权限修饰符(public, protected, private 或 default) 数据类型关键字定义[^5]。 #### 局部变量 局部变量仅限于特定的方法、构造器或语句块中使用。它们存在于栈内存上,当方法执行完毕后即被清除。因此,局部变量的作用范围非常有限,只在其声明的地方可见并可用。如果同名的情况下,函数内部会优先考虑局部变量而不是外部相同名称的其他类型的变量[^2]。 #### 所谓“全局变量” 需要注意的是,“全局变量”的概念并不适用于Java标准语法;通常所说的“全局变量”,实际上指的是静态(static) 变量或者是类级别的成员变量。这类变量在整个应用程序范围内都是可访问的,只要通过相应的类名就能获取其值,无需先实例化该类的对象。然而,严格来说这并不是真正的全局变量,因为仍然受限于包保护机制其他安全措施[^3]。 #### 关键差异总结 - **作用域**: 成员变量可以在整个类及其子类中访问;局部变量则局限于所在的方法体内;所谓的“全局变量”实际上是带有`static`属性的成员变量,可通过类名直接引用。 - **生存周期**: 成员变量伴随对象的存在而存在;局部变量存活期较短,一般不超过一次完整的流程控制结构(如循环体外)。对于标记为 `static` 的成员变量而言,它会在加载类时初始化,并一直持续到JVM终止运行为止[^4]。 ```java class VariableDemo { // 成员变量 (也称为实例变量) int memberVariable; static int classLevelStaticVar; // 类级别静态变量 void methodExample(){ int localVar = 10; // 局部变量 System.out.println(localVar); // 访问局部变量 System.out.println(memberVariable); // 访问成员变量 System.out.println(classLevelStaticVar); // 访问静态变量 } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值