Java 堆栈 和方法区的区别和联系详解。

一、直接上图

在这里插入图片描述

1.举个例子

构造一个Person类

public class Person{
public String name;
public int age;
	Person(String name,int age){
		this.name = name;
		this.age = age;
	}
}

实例化person类

Person 张三  = new Person("张三",18);
  1. 引用变量 张三 (指向堆中张三实例的地址)储存在栈中
  2. 张三实例(Person(“张三”,18))储存在堆中,
  3. 张三的实例的class,本类(Person),加载后储存在,方法区,

二、方法区的好处:提高性能。

1. 常量池

(1)避免重复的创建对象:销毁对象而影响系统性能,实现对象的共享
(2)节省内存空间: 常量池的所有的相同的字符串的常量被合并,只占用一个空间
(3)节省运行时间:比较字符串时候, ( == ) 比 equals() 快,对于2个引用的变量,只用 ( == )

三、常用的面试题

1. String a = “str” 和 String b = new String(“str”) , a == b ?为什么?

回答:
a==b 是false的

  1. String a = “str” ; 会先在方法区的常量区找是否有字符串 “str”,有的话,直接把 方法区的常量区的"str"地址赋值给 a ,
    没有的话就在方法区的常量区开辟一块空间,储存 "str"并赋值"str"的地址给a,
    所以无论如何a的地址是指向方法区的常量区的
  2. String b = new String(“str”)的 b的地址是指向堆空间的

2. String a2 = “hello” ,String b2 = “he”+“llo”; a == b ?为什么?

回答
a2 == b2 为 true
b2 虽然为动态拼接 但是所有的拼接成分都是已知的储存在方法区的常量,这种拼接编译器会自动帮你优化好。

但是如果
String a2 = “hello”
String c2 = new String(“llo”)
String b2 = “he”+c2;

a2 == b2 为false;
因为c2指向储存在堆中的数据所以并不在方法区的常量区,b2会创建一个新的地址,鬼知道b2的地址在哪里,只有运行的时候才知道。

原创文章 132 获赞 11 访问量 4687

猜你喜欢

转载自blog.csdn.net/jarvan5/article/details/106100885