堆,栈,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类型的特殊类型,关键在于是否生成了对象以及字符串池的定义。

原文地址:https://www.cnblogs.com/MedivhQ/p/4074993.html