一. 静态和非静态

1. 概念介绍

  ① 静态类(被static修饰) vs  普通类(没有被static修饰)

  ② 静态成员:被static修饰的成员,比如:静态方法、静态字段等

  ③ 普通成员(实例成员):不被static修饰的成员,比如:普通方法、普通字段

2. 运行机制

  ① 静态成员在程序运行的时候会“先于”实例成员被加载到内存中,静态成员不需要单独创建,当然静态类也不能被实例化。

  比如:静态字段和静态构造函数只有在程序第一次使用该类之前被调用,而且只能调用一次,利用该特性,可以设计单例模式。

补充单例模式的代码:

 View Code

public class STwo
    {
        /// <summary>
        /// 模拟耗时的构造函数
        /// </summary>
        private STwo()
        {
            long result = 0;
            for (int i = 0; i < 1000000; i++)
            {
                result += i;
            }
            Thread.Sleep(1000);
            Console.WriteLine("{0}被构造...", this.GetType().Name);
        }

private static STwo _STwo = null;
        /// <summary>
        /// 静态的构造函数:只能有一个,且是无参数的
        /// 由CLR保证,只有在程序第一次使用该类之前被调用,而且只能调用一次
        /// </summary>
        static STwo()
        {
            _STwo = new STwo();
        }

public static STwo CreateIntance()
        {
            return _STwo;
        }
    }

 View Code

public  class SThird
    {
        /// <summary>
        /// 模拟耗时的构造函数
        /// </summary>
        private SThird()
        {
            long result = 0;
            for (int i = 0; i < 1000000; i++)
            {
                result += i;
            }
            Thread.Sleep(1000);
            Console.WriteLine("{0}被构造...", this.GetType().Name);
        }
        /// <summary>
        /// 静态变量:由CLR保证,在程序第一次使用该类之前被调用,而且只调用一次
        /// </summary>
        private static SThird _SThird = new SThird();

public static SThird CreateIntance()
        {
            return _SThird;
        }
    }

  ② 实例成员:只有创建了对象(即进行了类的实例化)才会存在于内存中。

  证明:在StaticInstroduceDemo类中的静态变量a上加断点(方法体内部加断点,两次实例化类的时候加断点),然后在客户端实例化两次 StaticInstroduceDemo类,分别调用ShowStaticInstroduce方法,

  发现:第一次实例化的时候进入静态变量a上的断点,然后在调用对应的方法,而第二次实例化的时候不再进入静态变量a上的断点,直接进入调用的方法。从而验证了:静态成员优先于实例成员进入内存,且只在第一次使用该类的时候进行初始化分配内存,后续将不在分配.

3. 基于以上运行机制可以得出以下几个结论

① 普通类:

  a. 普通类中可以存在静态成员(静态方法、静态字段),但里面的静态方法不能调用普通类中的普通字段<普通类没有实例化的话,普通字段是不存在的>。

  b. 普通类中普通方法可以调用里面的静态字段<静态成员先于实例成员加载到内存中>

eg:

② 静态类:

静态类中只能存在静态成员(静态方法和静态字段)

4. 调用形式

  ① 静态成员: 类名.静态成员名

  ② 实例成员: 实例名.实例成员名

5. 声明周期

  ① 对于C/S程序:每启动一次,相当于一次生命周期,关闭程序生命周期结束,多次打开客户端程序互不干扰。

验证:上述的ShowStaticInstroduce方法,两次实例化后调用输出的结果是2,3 。此时我再打开一个客户端,结果依旧是2,3,这也很好证明了声明周期的问题。

  ② 对于B/S程序:static修饰的成员存储在服务器端中,与客户端关闭与否无关。《详见HomeController下的TestStatic方法》

验证:打开不同浏览器,分别调用TestStatic1方法,发现每点击一次按钮,返回值增加1,关闭该浏览器,重新点击,返回值在原基础上加1. 关闭IIS重新运行,返回值重新计数。证明:在B/S模式下,static修饰的成员存储在服务器端内存中,与客户端关闭与否无关。

6. 使用场景

  ① 对于C/S程序:static修饰的变量可以当作缓存来使用。

  ② 对于B/S程序:可以利用static的特性来设计单例模式,或者面向多线程存储数据,进行资源的共享<PS: 不考虑性能方面问题和一些极端情况>。

  ③ 作为工具类,全局资源共享。

二. 拆箱和装箱

1. 补充两个概念:

  值类型:int、double、char、bool、decimal、struct、enum

  引用类型:各种class类、string、数组、接口、委托、object

2. 装箱:

  将值类型→引用类型

3. 拆箱:

  将引用类型→值类型

4. 经典面试题

请问下面代码涉及到几次拆箱和装箱。

分析:

  ① 第一次装箱发生在 object m2 = m1;

  ② 第一次拆箱发生在 (int)m2 上;

  所以很多人认为答案是:1次装箱和1次拆箱,显然是不对的。

    我们继续分析,熟悉 Console.WriteLine原理的知道内部调用string.Concat()方法进行拼接,而Contact有很多重载,F12看源码可知,

    该案例只能使用 public static String Concat(object arg0, object arg1); 这个重载,

    所以第2次装箱和第3次装箱发生在 m1→object 和(int)m2→object上。

  所以最终答案是 1次拆箱和3次装箱

5.  特别注意:用什么类型进行装箱的,拆箱就拆成什么类型,否则会抛异常,无法进行类型转换。

PS:如果你对.Net其他知识感兴趣,可以参考  DotNet进阶系列(持续更新)  ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新)

那些年我们一起追逐的多线程(Thread、ThreadPool、委托异步调用、Task/TaskFactory、Parallerl、async和await)

第十七节:易混淆的概念(静态和非静态、拆箱和装箱)相关推荐

  1. 黑马程序员--高新技术--静态导入,基本数据类型拆箱与装箱,享元设计模式

    静态导入 import语句可以导入一个类或某个包中的所有类 import static语句导入一个类中的某个静态方法或所有静态方法或静态变量 使用静态导入可以使被导入类的静态变量和静态方法在当前类直接 ...

  2. C语言中易混淆的标识符,C语言指针中易混淆的概念

    C语言指针中易混淆的概念 一.数组指针与指针数组的区别 考虑数组的指针的时候我们要同时考虑类型和维数这两个属性.换一句话,就是说一个数组排除在其中存储的数值,那么可以用类型和维数来位置表示他的种类. ...

  3. java的静态与非静态 及其代码演示示例

    静态与非静态的概念 运行Java应用程序时,在实际的代码运行之前的一个步骤是加载类,具体点说,在Java SE 8的JVM中,需要先把类加载到Metaspace.如果类中有静态成员,加载类时会在hea ...

  4. java中静态是什么,java中静态和非静态有什么区别

    首先我们先来说说jvm内存模型: jvm内存分为:方法区.堆.栈和程序计数器. 下面我们来简单的说说方法区.栈和堆: 方法区:是各个线程共享的区域,存放类信息/常量/静态变量: 栈:其实每个线程都会分 ...

  5. C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态

    C#基础--类/接口/成员修饰符,多态.重载.重写,静态和非静态 类/接口/成员修饰符 C#修饰符---接口: 接口默认访问符是internal 接口的成员默认访问修饰符是public C#修饰符-- ...

  6. java 静态与非静态之间的访问规则简述

    java 静态与非静态之间的访问规则简述 1.静态与静态之间直接访问 2.非静态(实例级别)访问静态直接访问 3.静态访问非静态(实例级别),必须先创建对象再访问 package com.qfedu. ...

  7. C# 静态和非静态的区别

    静态标记 – static //静态方法 public static void Max(){ } //非静态方法 public void Max(){ }//静态类 public static cla ...

  8. 开发三年,java静态和非静态的这些弯弯绕绕你真的知道吗?

    问 Java 中,为什么不允许从静态方法中访问非静态变量? 了解特点 静态方法.属性:类加载时调用创建,通过类名直接调用,子类可继承不可重写 普通方法.属性:new对象时创建.注意new对象的时候 静 ...

  9. C# 面向对象编程 1 面向对象类,静态和非静态的区别,构造函数,new关键字 ,析构函数

    C# 面向对象编程 1 文章目录 C# 面向对象编程 1 1.面向过程-----> 面向对象 2.类 3.静态和非静态的区别 4.构造函数 5.new关键字 6. 析构函数 1.面向过程---- ...

最新文章

  1. JAVA多线程和并发基础面试问答
  2. 为什么DL模型能够正确分类?SCOUTER(ICCV21')从“正”“反”方面说服你。
  3. 连接svn认证失败有那些原因_windows局域网搭建svn服务器
  4. CSS 小结笔记之滑动门技术
  5. 解决:-bash: unzip: command not found (Linux 中 unZip/Zip 的安装及使用)
  6. php 系统环境变量引用,PHP 系统变量 环境变量
  7. action script3.0殿堂之路_【日本乐坛传奇】松任谷由实是谁?新音乐女王的登基之路!...
  8. DUMP文件分析6:简单的堆破坏示例
  9. Cere Network将在DAOMaker平台启动首次种子私募轮社区融资
  10. 自动化测试--实现一套完全解耦的测试框架(三)
  11. 中value大小_如何在Spring/SpringBoot 中做参数校验?你需要了解的都在这里!
  12. 电气器件系列三十三:步进电机驱动器
  13. 对数周期天线hfss建模_07 HFSS软件二次开发在对数周期天线设计中的应用
  14. 阿里巴巴国际站外贸邮开通的操作步骤
  15. 心知天气api PHP,心知天气API的应用实例
  16. vue H5移动端项目 真机测试配置
  17. 地址解析(仅供参考与学习)<Java>
  18. 【区块链 | AAVE】一文讲清-DeFI王者AAVE最新的稳定币GHO提案
  19. amazon开发者申请,pii权限申请
  20. 车辆占用应急车道识别抓拍系统 opencv

热门文章

  1. vue-touchjs
  2. FFmpeg开发实战(三):FFmpeg 打印音视频Meta信息
  3. 算法训练 6-1 递归求二项式系数值
  4. iOS MD5 (消息摘要算法5)
  5. 初识JavaScript,感觉整个人都不好了。。。
  6. where 1=1低效?
  7. WinCE 5.0 WIFI 无线网卡的配置和建立连接(转)
  8. [密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第29篇]什么是UF-CMA数字签名的定义?
  9. UVa-10820 Send a Table 欧拉函数
  10. ajax 微信code获取_获取链接的参数,判断是否是微信打开,ajax获取数据