java中局部静态变量生命周期和实例变量的生命周期有什么区别?

主题信息(必填)
主题描述(最多限制在50个字符)
申请人信息(必填)
申请信息已提交审核,请注意查收邮件,我们会尽快给您反馈。
如有疑问,请联系
CSDN &《程序员》编辑/记者,投稿&纠错等事宜请致邮
你只管努力,剩下的交给时光!
如今的编程是一场程序员和上帝的竞赛,程序员要开发出更大更好、傻瓜都会用到软件。而上帝在努力创造出更大更傻的傻瓜。目前为止,上帝是赢的。个人网站:。个人QQ群:、
个人大数据技术博客:
一、什么是变量:就是内容可以改变的量,它与常量相对应。而这三大变量实际上是从变量的作用域来定义和划分的。
1、类变量,是归属类的变量,它是通过在定义类的属性的时,增加static修饰符,所以又称为静态变量。类变量不仅可以直接通过类名+点操作符+变量名来操作,也可以通过类的实例+点操作符+变量来操作,大多数情况下,采用前者操作方式,一来不能够有效地使用该变量,二来能够表示该变量就是类变量。
2、实例变量,是归属于类的实例的变量,又称为成员变量,没有经过static修饰。实例变量只能通过类名的实例+点操作符+变量来操作。
不管是类变量,还是实例变量,都可以设置Java的访问修饰符,若是需要公开操作,你可以在这些变量前面添加public访问权限;若是只限于所在类中操作,你可以在这些变量前面添加private访问权限。
3、局部变量就是在类中方法体里面所定义的变量,不管是方法的形参,还是方法体内所定义的变量都是局部变量。局部变量的作用域是以其所在方法体的头大括号开始到尾大括号结束。
4、变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写。如果局部变量的名字和成员变量的名字相同,要想在该方法中使用成员变量,必须使用关键字this
运行结果为:
第一个输出:类体方法中定义的name
第二个输出:类体定义变量:name 成员变量调用必须用到this关键字
二、成员变量和局部变量的区别
成员变量:
1、成员变量定义在类中,在整个类中都可以被访问。
2、成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
3、成员变量有默认初始化值。
局部变量:
1、局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
2、局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
3、局部变量没有默认初始化值
在使用变量时需要遵循的原则为:就近原则
首先在局部范围找,有就使用;接着在成员位置找。
成员变量和类变量的区别
由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。
不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量。
[java] view plain copy print?
class MyAdd {
int count = 0; //成员变量计数器
static int sum = 0; //静态变量计数器
MyAdd(String name){
this.name =
public void myAddMethod() {
System.out.println(name+”调用成员变量后的值:”+count);
public void staticAddMethod() {
System.out.println(name+”调用类后变量的值:”+sum);
public class TestThis {
public static void main(String[] args) {
MyAdd add1 = new MyAdd(“add1”);
MyAdd add2 = new MyAdd(“add2”);
add1.myAddMethod();
add2.myAddMethod();
add1.myAddMethod();
add1.staticAddMethod();
add2.staticAddMethod();
add1.staticAddMethod();
class MyAdd {
输出结果:
成员变量和类变量的区别:
1、两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2、调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3、别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4、数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
static:★★★ 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。
1、想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。
2、被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。
3、静态随着类的加载而加载。而且优先于对象存在。
1、有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。
2、静态方法只能访问静态成员,不可以访问非静态成员。
因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
3、静态方法中不能使用this,super关键字。
因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。
什么时候定义静态成员呢?或者说:定义成员时,到底需不需要被静态修饰呢?
成员分两种:
1、成员变量。(数据共享时静态化)
该成员变量的数据是否是所有对象都一样:
如果是,那么该变量需要被静态修饰,因为是共享的数据。
如果不是,那么就说这是对象的特有数据,要存储到对象中。
2、成员函数。(方法中没有调用特有数据时就定义成静态)
如果判断成员函数是否需要被静态修饰呢?
只要参考,该函数内是否访问了对象中的特有数据:
如果有访问特有数据,那方法不能被静态修饰。
如果没有访问过特有数据,那么这个方法需要被静态修饰。
成员变量和静态变量的区别:
1、成员变量所属于对象。所以也称为实例变量。
静态变量所属于类。所以也称为类变量。
2、成员变量存在于堆内存中。
静态变量存在于方法区中。
3、成员变量随着对象创建而存在。随着对象被回收而消失。
静态变量随着类的加载而存在。随着类的消失而消失。
4、成员变量只能被对象所调用 。
静态变量可以被对象调用,也可以被类名调用。
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。
**学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码: 我们一起学Java!**浅谈静态变量、成员变量、局部变量三者的区别_java
作者:用户
本文讲的是浅谈静态变量、成员变量、局部变量三者的区别_java,
静态变量和成员变量的区别:
A:所属不同
静态变量:属于类,类变量
成员变量:属于对象,对象变量,实例变量
B:内存位置不同
静态变量:方法区的静态区
成员变量:堆内存
C:生命周期不同
静态变量:静态变量是随着类的加载
静态变量和成员变量的区别:
A:所属不同
静态变量:属于类,类变量
成员变量:属于对象,对象变量,实例变量
B:内存位置不同
静态变量:方法区的静态区
成员变量:堆内存
C:生命周期不同
静态变量:静态变量是随着类的加载而加载,随着类的消失而消失
成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失
D:调用不同
静态变量:可以通过对象名调用,也可以通过类名调用
成员变量:只能通过对象名调用
成员变量和局部变量的区别:
A:在类中的位置不同
成员变量:在类中方法外
局部变量:在方法定义中或者方法声明上
B:在内存中的位置不同
成员变量:在堆内存
局部变量:在栈内存
C:生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
D:初始化值不同
成员变量:有默认初始化值
局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。
注意事项:
局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。
以上就是小编为大家带来的浅谈静态变量、成员变量、局部变量三者的区别的全部内容了,希望对大家有所帮助,多多支持云栖社区~
以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java静态局部变量
静态局部变量、局部变量和成员变量、静态局部变量初始化、c 局部静态变量、成员变量 局部变量,以便于您获取更多的相关知识。
稳定可靠、可弹性伸缩的在线数据库服务,全球最受欢迎的开源数据库之一
6款热门基础云产品6个月免费体验;2款产品1年体验;1款产品2年体验
弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率
开发者常用软件,超百款实用软件一站式提供
云栖社区()为您免费提供相关信息,包括
,所有相关内容均不代表云栖社区的意见!Java 中,究竟如何使用静态变量? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
Java 中,究竟如何使用静态变量?
11:17:53 +08:00 · 2447 次点击
静态变量的优点
内存中只保留一份,不需要频繁创建和销毁
静态变量的缺点
破坏面向对象类的封装性
生命周期长
可能产生其他问题?...
曾见过一个大牛的观点:
代码中的静态变量最好不要超过 10 个。
而且静态变量要去序列化,当找不到这个变量时再解冻。
他说的是否有道理?
现在有这样一个需求:
子类处理具体业务,需要异步。
父类提供一个线程池,子类处理的时候,直接 submit 一个 Runnable 。
多个子类想共享一个父类的线程池。
如果我把这个 thread pool 定义为 static ,会有什么坏处吗?
33 回复 &| &直到
02:07:40 +08:00
& & 12:08:44 +08:00
如果只是说坏处的话,如果涉及到应用场景的话,我相信每个人都有自己的想法,
这个问题应该是 “如果我把这个 thread pool 定义为 static ,会有什么好处吗?”
前文提到 “内存中只保留一份,不需要频繁创建和销毁”
你的应用需要频繁创建 ThreadPool ?
& & 12:30:45 +08:00
@ 感谢你的回复
前文提到的只是静态变量的优点,和场景无关。
应用肯定不需要频繁创建 threadPool ,而且想如何去避免频繁创建 threadPool 。
所以才会去假设,将 threadPool 设置成 static 后,会不会实现我预期的目的,
而且是否可能带来什么问题。
& & 12:32:14 +08:00
如果不设置为 static ,每 new 一个子类的时候
都会创建一个新的 threadPool 吧
我就是希望可以避免这个问题,能让所有子类共享父类的 threadPool 。
& & 13:02:42 +08:00
没必要为了别人因为他们项目特点总结的条条框框影响自己项目架构 ThreadPool 弄成 Static 再正常不过了
& & 13:27:47 +08:00
根据实际需求来,很明显,这里需要 static
& & 13:41:11 +08:00
如果不设置为 static ,每 new 一个子类的时候
都会创建一个新的 threadPool 吧
我就是希望可以避免这个问题,能让所有子类共享父类的 threadPool 。
static 确实能避免上述的问题,大胆的写吧
& & 13:43:17 +08:00
@ 或者你自己实现一个单例的 ThreadTaskService ,父类里面定义这个 Service,也一样能达到你想要的效果
& & 13:44:18 +08:00 via iPhone
1 static 不应该使用一定意义上是正确的
2 threadpool 应该注入来解决
& & 13:53:11 +08:00
静态常量可以有
& & 14:26:22 +08:00
static 可以,系统启动时 生成一个单例的 pool 也可以
& & 15:10:34 +08:00
1 使用单例化
2 注入
& & 15:26:25 +08:00
感谢回复 会小心谨慎的使用 static
& & 15:30:58 +08:00
感谢回复 单例是一种解决方式
不过仍有些疑惑 单例不也是通过 static 方式实现的吗
是否有以下假设:
将需要共享的元从宿主中分离出来,做成单例(仍是 static 的)
就避免 static 可能产生的问题?
& & 15:37:46 +08:00
@ 非常感谢
开拓了新思路
再请教下 通过 Constructor 还是 seter 来实现呢?
在我看来既然已经实现了异步方式, threadPool 的实例是一定要注入的
既 使用 Constructor 方式来实现
但在子类的 Constructor 里,还需要传入其他业务相关的参数
感觉一个业务类的 Constructor 里并列注入一个 threadPool ,看起来有点突兀- -
由于业务能力尚浅,可能有些比较幼稚的观点,请指教
& & 15:38:03 +08:00
@ 感谢回复
& & 15:39:44 +08:00
单例可以通过 static 实现,也可以你自己在系统启动时仅在系统内 生成一个 final 类型的即可,类似 spring 中的 bean 貌似都是单例的
& & 16:24:17 +08:00
@ Spring 的 Bean 是 singleton 这个只是 scope 默认配置而已,你配个 prototype 就不一样了。
单例什么的和 static field 没有必然关系,只是因为 static field 一定只存在一份,所以经常用来做单例而已。
什么 double check idiom 之类的
& & 17:24:53 +08:00
只应该拿来定义常量。
如你问题里描述的需求,应该用 Spring 或者其他框架来管理对象的生命周期,而非依赖语言特性。
& & 21:02:30 +08:00
static 不建议使用主要有两点:容易造成内存泄漏,强耦合,强耦合的问题尤其严重。
注入的方式有很多种,不依赖框架的话,构造方法或者 setter 方法或者单独的 init 方法都是可取的,用 Spring 之类的依赖注入当然就更简单了,其它比如容器提供 jndi 注册也是一种选择,总而言之有很多种方法可以实现单例, static 是看上去省事但却是最坏的选择
& & 01:06:30 +08:00
这个需求很适合 static ,不过可以考虑下真的是这个需求吗?譬如“多个子类想共享一个父类的线程池”,高耦合,子类想访问线程池中的对象?或许可以抽象出一个线程池控制器,通过代理者进行交互。因此最好从设计上改变,减少不必要 static 的使用。
& & 02:17:14 +08:00
一般的原则是 static 和变量可接受的组合是 final static ,即用来定义常量;不要有任何 static 的方法。现代 java 编程里,如果出现非 final 的 static 申明,基本上都是不可接收的
& & 09:00:17 +08:00
@ 感谢回复
你说的有道理,可能我的设计本身存在问题。
& & 09:02:36 +08:00
感谢您的再次回复
如果设计不变,我会使用注入的方式来代替 static
& & 09:40:53 +08:00
@ 说设计什么的可能有点虚,最直接的原因是这样的代码非常难写 unit test 。尝试一下就会有感觉了。
& & 09:42:28 +08:00
@ 感谢您的回复
您给出的设计给了我很大启示
还想和您探讨下 “'多个子类想共享一个父类的线程池'会造成高耦合” 的问题
您是指 多个子类 与 共同父类 之间的耦合吗
如果我在父类中将与 threadPool 相关的操作 写成模板
在子类中去重写实际处理业务的方法 对于子类而言 是否异步是透明的(或者尽量透明)
这样还会产生耦合的现象吗
可能我对耦合的定义仍然不是那么明晰 请指教
& & 09:45:42 +08:00
@ 感谢回复
您的观点我完全赞同
只是实际工作中我在极力避免的过程中会遇到问题
除本文所指问题外
例如 Utils 类中,大家的惯例是 private Constructor
public 方法全部 static
您觉得这样的情况如何避免?
& & 09:59:38 +08:00
@ 再补充下
我的问题中提到&子类去 submit 一个 runnable&
如果修改我上面说的实现,做出以下的实现:
1. 父类中的 thread pool 相关操作对于每个子类都是相同的,是一个共同的模板。
2. 由于是操作相同,当父类的线程机制做调整时,其他全部子类同时受影响。(子类是并列的概念,只是业务有区分)
如果实现共享父类的 thread pool ,会让全部的并行子类都单向依赖这个 thread pool 。
会产生高耦合的危害吗?
换句话说,当这个被依赖的模块,对于依赖它的模块的处理是统一的。
这样的情况,会产生高耦合的危害吗?
& & 10:15:51 +08:00 via Android
那些说注入的仿佛自己没有间接用 static 。。。乖乖用 Executor 不就好咯。。。接口标准库都封装好了。
& & 12:12:52 +08:00
@ 如果“父类中的 thread pool 相关操作对于每个子类都是相同的”,那么放父类中做成”模板“,并且把对父类 threadpool 的操作放在父类方法中,这样对于子类,弗雷德 thread pool 是透明的,这样就不会高耦合吧。如果让子类都直接访问父类 static 对象,不符合迪米特法则,就是高耦合。
& & 12:19:13 +08:00
@ ”您是指 多个子类 与 共同父类 之间的耦合吗 “不是,我指的是多个子类之间的耦合。本来,子类和父类之间不存在高耦合的问题,因为继承的目的就是公有一些方法和属性,然而你把所有子类产生的对象提交到父类的一个线程集合里,强行让他们互相可以引用,这样就让子类之间耦合起来了。
& & 15:07:13 +08:00
你也知道静态变量的特点了,在符合这个特点,或者是使用这个最方便的时候可以用
& & 00:32:00 +08:00
凡是单例模式的通常都应该用 static
基于回收池或者重用池模式的,回收池实例声明周期为逻辑声明周期一致,因此,如果你是对 app 的回收池,通常他也是单例静态的
& & 02:07:40 +08:00
@ 说明“大家”都还在用老式的设计模式,即用 java 本身的特性来管理一个类的生命周期。现代的设计模式是不要自己实现生命周期,把所有 java 类都写成 pojo 。这种 pojo 不应该有非 public 的 constructor ,不应该存在 static 的方法。你们公司里如果还在用这种老式的设计模式的话,我第一反应就是你们公司不做单元测试
& · & 2616 人在线 & 最高记录 3541 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.0 · 185ms · UTC 03:26 · PVG 11:26 · LAX 20:26 · JFK 23:26? Do have faith in what you're doing.Java中局部变量、静态变量和实例变量的区别
(1)JAVA的成员变量有两种:
一种是被static关键字修饰的变量,叫静态变量(类变量),另一种没有static修饰,为实例变量;
类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,被类的所有实例共享。静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期。
而实例变量取决于类的实例。每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期。
class Temp {
//实例变量&
& public static void main(String
& int t=1; //局部变量&
&&System.out.println(t&);
//打印局部变量&
& Temp a= new Temp(); //创建实例
&&System.out.println(a.t&);
//通过实例访问实例变量&
0 (成员变量具有缺省值
而局部变量则没有&)&
把代码改为:
public class Temp {
public static void main(String args[]){
System.out.println(t&);
//打印类变量
//局部变量&
System.out.println(t&);
//打印局部变量
Temp a= new Temp(); //创建实例
System.out.println(a.t&);
//通过实例访问实例变量
(3)局部变量:定义在方法内或语句块内,从属于方法或者语句块,在使用之前必须手动初始化;
&实例变量:定义在类里、方法外面,从属于对象,如果我们没有初始化,系统会初始化,规则如下:数字:0/0.0
& 布尔:false & char:\u0000
& 引用类型:null
&静态变量:也称类变量,定义在类内、方法外,从属于类,如果我们没有初始化,系统会初始化,规则如下:数字:0/0.0
& 布尔:false & char:\u0000
& 引用类型:null
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。}

我要回帖

更多关于 静态变量的生命周期 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信