字符串在内存中的存储方式(equals方法重写)

一、判断下面代码的输出结果是“true”还是“false”:

 1 package com.njupt.www;
 2 
 3 public class TestAA {
 4     public static void main(String[] args) {
 5         String str1 = "AA";
 6         String str2 = "AA";
 7         String str3 = new String("AA");
 8         System.out.println(str1 == str2);
 9         System.out.println(str1 == str3);
10         System.out.println(str1.equals(str3));
11         
12         Person p1 = new Person("AA", 10);
13         Person p2 = new Person("AA", 10);
14         System.out.println(p1 == p2);
15         System.out.println(p1.equals(p2));
16         
17 //        System.out.println("");
18 //        Person p4 = new Person("AA");
19 //        Person p5 = new Person("AA");
20 //        System.out.println(p4 == p5);
21 //        System.out.println(p4.equals(p5));
22     }
23 }
24 class Person{
25     private String name;
26     private int age;
27     public Person(String name){
28         this.name = name;
29         //this.age = age;
30     }
31     public Person(String name,int age){
32         this.name = name;
33         this.age = age;
34     }
35     public String getName() {
36         return name;
37     }
38     public void setName(String name) {
39         this.name = name;
40     }
41     public int getAge() {
42         return age;
43     }
44     public void setAge(int age) {
45         this.age = age;
46     }
47     public boolean equals(Object obj){
48         if(this == obj){
49             return false;
50         }else if(obj instanceof Person){
51             Person p = (Person)obj;
52             return this.name == p.name && this.age == p.age;
53         }else{
54             return false;
55         }
56     }
57 }

输出结果:

true
false
true
false
true

二、下面来分析下具体原因:(下面地址都是虚构出来的)

① String str1 = "AA"; 和 String str2 = "AA":str1和str2都指向同一个地址

字符串在内存中的存储方式(equals方法重写)

② String str3 = new String("AA"); str3指向堆空间new出来的一块地址,被new出来的区域又会指向字符串常量池中的AA地址

字符串在内存中的存储方式(equals方法重写)

③Person p1 = new Person("AA", 10);  Person p2 = new Person("AA", 10);

p1和p2引用指向的对象都是堆空间中重新new出来的,即所指向的地址是不一样的,“age”都初始化成“10”,“name”都指向字符串常量池中AA的地址“0x1111”

字符串在内存中的存储方式(equals方法重写)

三:总结

① 定义一个新字符串,它会先去字符串常量池中查找有没有一样的字符串,如果有直接指向该地址,如果没有再新创建该字符串

② 字符串1 == 字符串2,比较的是两个字符串的地址

③ equals方法比较的是两个对象所指向的具体的属性