静态成员和非静态成员的区别

 我来答
llzzcc66
2016-06-27 · 知道合伙人数码行家
llzzcc66
知道合伙人数码行家
采纳数:81385 获赞数:171487
公司运维员工

向TA提问 私信TA
展开全部
数据成员可以分静态变量、非静态变量两种.
静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.

非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..

一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数..

对于winApp来说,静态成员对于程序员本身省了很多事,而且因为静态成员驻留内存,在方法与方法之间传递共享数据的时候,所以静态成员成了我的首选..但是不要因为方便,大量使用,尤其是在内存紧张或者
用静态方法操作一些共享值的时候.或者要写多用户系统的时候,要慎之又慎.比如:
static int id = 0;
sql = "select * from table where id=" + id;

如果这样写的话,在单机测试的时候没有问题,但是在多人同时对数据进行测试的时候,就会有问题了.假如,A用户访问他的id是20,则id的值在内存中为20,而此时B用户访问,他的id是30,则id在内存中的值是30..A用户的id值则被更改了..如果此时你将这个方法用非静态成员来写,则不会出现这样的情况..因为非静态成员是你声明的时候,实例化的时候才会分配内存..所以A用户访问的时候,App会因为A实例化而给A用户的请求分配内存..而B用户访问的时候也一样会因为B用户的访问而分配内存..所以两个用户访问的是不同的内存块..所以不会出现数据覆盖和错乱的现象...

我想这样的情况应该能很好的说明静态变量和非静态成员的区别..

相对于webApp而言,在winApp下使用static的时候要比webApp下考虑的因素要少的多,因为webApp本来就是一个多用户的系统,所以使用static的时候更应该小心..

而我对static在webApp下的使用存在一个疑问,如果一个静态方法,例如:

static string aa(string str){
//经过一系列操作..
return str;
}

或者返回一个DataSet的静态方法
static DataSet aa(string str){
//经过一系列操作..
return DataSet;
}

这个时候,在访问量大的时候,程序出现了并发,会不会发生错乱??我以前的项目使用的公用函数类中使用了大量的静态方法,不过好在访问量不大,一直没有问题..在发这个文章之前,我查找了MSDN,CSDN,搜索了一些关于静态成员的文章,但是都没有一个明确的说明..虽然,自己在项目中也测试了这么长时间也没有问题..但是总觉得有这个可能发生..

不知道大家是否在项目中碰到类似的疑惑呢??请有过这方面经验的朋友指教..

答案:
不说是否滥用,如果你出现冲突,说明你没有理解静态成员变量和静态方法的区别,静态方法本身只是一段代码,不管怎么调用他都不会出现问题。但静态成员变量就不行了,他被所有用户共享,如果一个用户改变了他,肯定会影响到别人,这就是常说的并发冲突问题,一般来说在修改共享成员变量时要lock!

关于静态方法和实例方法的一些误区。

一、 静态方法常驻内存,实例方法不是,所以静态方法效率高但占内存。

事实上,方法都是一样的,在加载时机和占用内存上,静态方法和实例方法是一样的,在类型第一次被使用时加载。调用的速度基本上没有差别。

二、 静态方法在堆上分配内存,实例方法在堆栈上。

事实上所有的方法都不可能在堆或者堆栈上分配内存,方法作为代码是被加载到特殊的代码内存区域,这个内存区域是不可写的。

三、 实例方法需要先创建实例才可以调用,比较麻烦,静态方法不用,比较简单。
事实上如果一个方法与他所在类型的实例无关,那么它就应该是静态的,决不会有人把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤,没有麻烦简单一说。实际上上你可以把所有的实例方法都写成静态的,将实例作为参数传入即可。
有些方法看似与所在的实例无关,如IComparer.Compare方法,但实际上每一个实现这个接口的类都只会负责自己类型实例的比较,这是C#1.x规范中没有泛型所带来的历史遗留问题。
大部分静态方法是与类的实例有关的,如各种Parse方法,他做成静态的原因是他没有实例作为参数。其他的大多是出于语义或者其他目的的考虑。
Storm代理
2023-07-25 广告
StormProxies是一家国内优质海外HTTP代理商,拥有一个庞大的IP资源池,覆盖200多个地区,IP数量大且匿名度高。其优点还包括超高并发、稳定高效、技术服务等特点,同时提供HTTP、HTTPS以及SOCKS5协议支持。此外,Sto... 点击进入详情页
本回答由Storm代理提供
coco22
高粉答主

2018-04-05 · 说的都是干货,快来关注
知道大有可为答主
回答量:254
采纳率:100%
帮助的人:4.1万
展开全部

一、名称上的区别:

成员变量也叫实例变量;静态变量也叫类变量。

二、内存存储的区别:

成员变量存储到堆内存的对象中,静态变量存储到方法区的静态区中。

三、生命周期不同:

1)成员变量随着对象的出现而出现,随着对象的消失而消失。

2)静态变量随着类的出现而出现,随着类的消失而消失。

四、补充:

1.静态变量使用 static 修饰符进行声明;

2.在类被实例化时创建,通过类进行访问不带有 static 修饰符声明的变量称做非静态变量;

3.在对象被实例化时创建,通过对象进行访问;

4.一个类的所有实例的同一静态变量都是同一个值,同一个类的不同实例的同一非静态变量可以是不同的值;

5.静态函数的实现里不能使用非静态成员,如非静态变量、非静态函数等。

6.示例:

1)using System;

using System.Collections.Generic;
using System.Text;
namespace Example01
{
class Program
{
class Class1
{
public static String staticStr = “Class”;
public String notstaticStr = “Obj”;
}
static void Main(string[] args)
{

2)//静态变量通过类进行访问,该类所有实例的同一静态变量都是同一个值

Console.WriteLine(“Class1′s staticStr: {0}”, Class1.staticStr);
Class1 tmpObj1 = new Class1();
tmpObj1.notstaticStr = “tmpObj1″;
Class1 tmpObj2 = new Class1();
tmpObj2.notstaticStr = “tmpObj2″;

3)//非静态变量通过对象进行访问,不同对象的同一非静态变量可以有不同的值
Console.WriteLine(“tmpObj1′s notstaticStr: {0}”, tmpObj1.notstaticStr);
Console.WriteLine(“tmpObj2′s notstaticStr: {0}”, tmpObj2.notstaticStr);
Console.ReadLine();
}
}
}

4)结果:
Class1′s staticStr: Class;
tmpObj1′s notstaticStr: tmpObj1;
tmpObj2′s notstaticStr: tmpObj2。

本回答被网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2016-06-27
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
枚邈璩丹雪
2019-04-04 · TA获得超过3481个赞
知道大有可为答主
回答量:3054
采纳率:34%
帮助的人:453万
展开全部
大致有两点:
静态成员是属于类的而不是对象的,所以只有一份拷贝,并不在类的对象中都有副本;
静态数据成员的值在函数退出时不消失,作为下一次调用时的初值,所以可在各对象之间传递数值。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式