• 堆,栈,String


            栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。

    1)栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放,目的就在于最快速度取值,个人觉得栈就好比一个常量池,用到谁,谁就被指向,很少用到的,慢慢被内存释放掉。

    2)堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些,个人觉得堆是一个通讯录,写清楚了每个人的地址,真正想知道每个人住什么样的房子,那么就沿着这个引用找到这个值对应的内存位置,如果是原生数据类型,那么这些值就在栈中,如果是字符串就要视情况,再次判断。

      因为,原生数据类型的大小和生命周期,我们都是预知的,所以,它会存在栈中,如果定义一个int类型的变量,int a=3;那么首先会在栈中创建一个名为a的引用,然后在栈中寻找是否拥有值为3的地址,如果存在。那么将引用a指向这个地址,如果没有那么先开辟一个地址存放3这个值,再将引用a指向这个地址。原生数据类型值得修改,不会修改存放3这个地址的值,而是从栈中再去寻找是否有存放值为修改后的值得地址,没有的话那么继续开辟地址,有的话将引用指向这个地址。

      不同于其他封装类,String 比较特别,例如:String a="ccc";和 String a=new String("ccc");是有区别的,a="ccc"它不一定生成对象,如果栈中存在一个地址存放"ccc",那么a就直接指向栈中这个地址,如果没有,在堆中创建一个引用a,用于指向一个值为这个的地址。

       我个人理解是这样的,赋值运算一般属于编译过程,例如:String a="ccc";那么String a=new String("ccc");生成新对象应属于一个运行过程的动作,编译过程中会先寻找字符串中池中是否有值为“ccc”的变量,如果没有就在池中创建一个“ccc”,再在堆中创建一个引用指向池中这个地址,类似于new方法,字符串的拼接:String a="ccc";String b="vvvv";String c= a+b;这个过程也属于运行期间才知道的,所以,同样会在堆中创建一个新的对象。

       毕竟,也是个初学者可能理解的不是很深入,下面是一个简单的测试程序:

    public class StringTest
    {
            public static void main(String[] args)
            {
                String str = "ccc";
                
                String str1 = "ccc";
                
                boolean bo = (str.equals(str1));
                
                boolean b = (str==str1);
                
                String str2 =  new String("aaa");
                
                String str3 = "aaa";
                
                boolean bo1 = (str2.equals(str3));
                
                boolean b1 = (str2==str3);
                
                String str4 = new String("bbb");
                
                String str5 = new String("bbb");
                
                boolean bo2 = (str4.equals(str5));
                
                boolean b2 = (str4==str5);
                
                System.out.println(b);
                
                System.out.println(b1);
                
                System.out.println(b2);
                
                System.out.println(bo+"-----");
                
                System.out.println(bo1+"-----");
                
                System.out.println(bo2+"-----");
                
                Object obj = new Object();
                
                Object obj1 = new Object();
                
                boolean ob = (obj==obj1);
                
                boolean ob1 = (obj.equals(obj1));
                
                boolean ob2 = (obj.equals(obj));
                
                System.out.println(ob+"///");
                
                System.out.println(ob1+"///");
                
                System.out.println(ob2+"///");
                
                Student student =  new Student("zhangsan");
                
                Student student1 =  new Student("zhangsan");
                
                boolean ob3 = (student.equals(student1,student));
                
                System.out.println(ob3+"****");
                
                Teacher te = new Teacher("lisi");
                
                Teacher te1 = new Teacher("lisi");
                
                boolean ob4 = (te.equals(te1));
                
                System.out.println(ob4+"---");
                
                Book book =  new Book("java");
                
                Book book1 = new Book("java");
                
                boolean bb =  (book.autor==book1.autor);
                
                boolean bb1 = (book.name==book1.name);
                
                boolean bb2 = (book.autor.equals(book1.autor));
                
                boolean bb3 = (book.name.equals(book1.name));
                
                System.out.println(bb);
                
                System.out.println(bb1);
                
                System.out.println(bb2);
                
                System.out.println(bb3);
            }
    }
    class Student
    {
        String name;
        
        public Student(String name)
        {
            this.name=name;
        }
        public boolean equals(Student student,Student student1)
        {
            if(student.name.equals(student1.name))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
    class Teacher
    {
        String name;
        
        public Teacher(String name)
        {
            this.name = name;
        }
    }
    class Book
    {
        public static String name="ring";
        
        String autor ;
        
        public Book(String autor)
        {
            this.autor = autor;
        }
    }

    运行结果如下:

    true
    false
    false
    true-----
    true-----
    true-----
    false///
    false///
    true///
    true****
    false---
    true
    true
    true
    true

    所以可以认为String类型可以认为是介于原生数据类型与Objiect类型的特殊类型,关键在于是否生成了对象以及字符串池的定义。

  • 相关阅读:
    互联网人25岁毕业 拿一万块钱月薪 (转)
    在windows平台编译openAL Android 库
    lua简单包装
    libevent 简单学习
    cocos2dx中使用tolua++使lua调用c++函数
    《OpenGL超级宝典》编程环境配置
    快速排序、归并排序、堆排序三种算法性能比较
    二叉树的三种遍历的递归与非递归算法
    boost之bind
    boost之内存管理
  • 原文地址:https://www.cnblogs.com/MedivhQ/p/4074993.html
Copyright © 2020-2023  润新知