字符串在内存中的存储方式(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都指向同一个地址
② String str3 = new String("AA"); str3指向堆空间new出来的一块地址,被new出来的区域又会指向字符串常量池中的AA地址
③Person p1 = new Person("AA", 10); Person p2 = new Person("AA", 10);
p1和p2引用指向的对象都是堆空间中重新new出来的,即所指向的地址是不一样的,“age”都初始化成“10”,“name”都指向字符串常量池中AA的地址“0x1111”
三:总结
① 定义一个新字符串,它会先去字符串常量池中查找有没有一样的字符串,如果有直接指向该地址,如果没有再新创建该字符串
② 字符串1 == 字符串2,比较的是两个字符串的地址
③ equals方法比较的是两个对象所指向的具体的属性