• 关于堆栈的理解


    你想当一名合格的程序员吗,你想成为别人眼中的佼佼者吗?你想迎娶白富美吗?...哈哈,那你必须看完我的这篇博客,你才能实现你的梦想。首先,关于堆栈的内容其实已经在网上有很多的资料。写这篇博客,我也是被迫无奈的,在前端时间,工作中遇到了一个问题,在使用C#通过dll调用c++函数,就出现了堆栈理解不透彻而出现了问题,这个问题大概与同事研究了竟两个星期,才弄明白。好了,不废话了,进入正题。

    一.内存区域类型

    1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;

     a. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);

      b. 堆:存放所有new出来的对象;

      c. 静态域:存放静态成员(static定义的);

      d. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;

      e. 非RAM存储:硬盘等永久存储空间

     

    二、栈中放的东西,图示:

       如:int i = 2;//基本类型变量的数据

             String s = "adc"; //s为引用

             String s1 = new String("a"); //s1也是引用

    三、堆存放示意图:

    对于String类的对象特别说明一下:

    四、按值传入还是引用传入

      理解了堆栈数据存储,再来理解一下值传递和引用传递的概念;

      1、基本类型:

    public class ChangeGender(){
      public static void change(String gender){
         gender = "女";
         System.out.println("手术期间:gender="+gender);
      }
      public static void main(String[] args){
         String gender = "男";
         System.out.println("变性前:gender="+gender);
         change(gender);
           System.out.println("变性后:gender="+gender);
    
      }
    }
    输出结果为:
    变性前:男
    手术期间:女
    变性后:男

     

       经过了痛苦的手术后,发现自己还是个男的,这是为啥?换个写法你就懂了:

    public class ChangeGender(){
      public static void change(String gender){
         girl= "女";
         System.out.println("手术期间:gender="+gril);
      }
      public static void main(String[] args){
         String boy= "男";
         System.out.println("变性前:gender="+boy);
         change(gender);
           System.out.println("变性后:gender="+boy);
    
      }
    }
    输出结果为:
    变性前:男
    手术期间:女
    变性后:男

     

       懂了吧,传给change()方法的参数值由boy传递,传完就由girl这个变量来处理了,手术期间的那个值是girl这个变量的值,手术前后的那个值是boy的。这个过程可以用一个故事总结一下:一个男人不想做男人了,准备做手术换个性别,于是打电话给快递小哥(变量boy)把他送到医院手术台上,快递小哥见到医生后,把那个男的交给了会变性的医生(方法change()),快递小哥就走了(快递小哥还是快递小哥),医生开始工作,把他的性别变成女的(girl="女"),那个男的确实手术成功了,只是我们打印的变性后的属性是快递小哥的。故事结束,完美!

    2、引用传值

       引用要这样来理解:它是一根绳子,它系着一个球(对象),但它不是球(对象),我们想找到球(对象),就得先找对应的绳子。

     

    看例子:

    public class User{
      private String age;
      public void getGirlAge(User user){
         user.setAge("18");
      }
    // get,set 方法
      public String getAge(){
       return age;
      }
      public void setAge(String age){
        this.age= age;
      }
      public static void main(String[] args){
        User user = new User();
        user.setAge("20");
        user.getGirlAge(user);
        System.out.println(user.getAge());
      }
    }
    输出结果:18

     

    输出的结果是什么?

    18

    为啥是这个结果,还是来说个故事,你同学给你介绍对象,说这姑娘白白嫩嫩,漂亮地一塌糊涂,你说好呀好呀,那她多大呀?你同学是马大哈,记不得年龄,就跟你说20岁(user.setAge("20")),然后你说确定吗?我才19岁,年龄大的一概不考虑,于是你同学就去找她的年龄(public void getGirlAge(User user)),得到了年龄并把这个年龄保存在大脑中(user.setAge("18")),然后打电话跟你说的时候,把年龄的信息从大脑里拿出来(user.getAge()),18岁是你可以接受的年龄,于是你们就安排见面了...再一次,完美。

    那再加个东西,你们看看:

    public class User{
      private String age;
      public void getGirlAge(User user){
         user = new User();//创建新的user对象
         user.setAge("18");
      }
    // get,set 方法
      public String getAge(){
       return age;
      }
      public void setAge(String age){
        this.age= age;
      }
      public static void main(String[] args){
        User user = new User();
        user.setAge("20");
        user.getGirlAge(user);
        System.out.println(user.getAge());
      }
    }

    这里输出的值是20,看来对象是谈不成了,这过程中到底发生了什么呢?原来是你的同学找那个姑娘的年龄的时候,发现那个姑娘把你同学拉黑了,你同学好面子,还是得给你介绍,于是又找了一个新的姑娘(user=new User();),还把年龄设成了18岁,你等啊等,等了半年也没等到,于是你开始着急了,想知道这个姑娘的年龄到底是多少,于是打印输出姑娘年龄,可是这个姑娘还是第一个姑娘(你也根本就不知道还有第二个姑娘),得到的就是20,年龄虽然比你大一点,可是半年时间,你也想清楚了,年龄大一点体贴也挺好。于是。。。好了,依然完美!

    就扯这么多,堆栈中放的东西都是固定的,大家记忆一下就好,很简单的。

     

  • 相关阅读:
    【原创】构建高性能ASP.NET站点之一 剖析页面的处理过程(前端)
    .NET 并行(多核)编程系列之七 共享数据问题和解决概述
    架构设计解惑
    项目开发经验谈之:设计失败的挫败感
    项目开发经验谈之:忆第一次设计Framework
    盲目的项目开发
    扩展GridView之添加单选列
    日期转换格式
    动手完善个性化弹出提示框的过程及乐趣
    SQL开发中容易忽视的一些小地方(六)
  • 原文地址:https://www.cnblogs.com/ysq0908/p/5838339.html
Copyright © 2020-2023  润新知