Java堆栈
Java把内存划分为两种:一种是栈内存,一种是堆内存。
基本数据类型的变量和对象的引用变量都在函数的栈内存中分配。
堆内存用来存放new创建的对象和数组
Java数据类型
1、基本数据类型
数值型:byte short int long float double
字符型: char
布尔型:boolean
他们之间的比较,使用==,比较的是他们的值。
2、引用数据类型
数组 类 接口
当他们用==进行比较的时候,比较的是他们堆内存中存放的地址,所以同一个new出来的对象,比较后结果是true,否则是false。
JAVA当中所有的类都是继承Object这个父类的,Object类中定义了一个equals方法,这个方法的实现实质上还是比较对象的在堆中的内存地址,也有一些类对这个方法进行了覆盖,例如String类,这些类中equals有其自身的实现,所以不再是比较堆内存中的存放地址了。
Object类中的equals实现:
1 public boolean equals(Object obj) { 2 return (this == obj); 3 }
String类中equals实现:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
代码示例:
package com.fwj.teststring; public class TestString { public static void main(String[] args) { String str1 = "hello world"; String str2 = "hello world"; if(str1==str2) System.out.println("str1==str2"); else System.out.println("str1!=str2"); } }
运行结果:
str1==str2
这是由于str1和str2引用了同一个String对象
再看下边示例:
package com.fwj.teststring; public class TestString { public static void main(String[] args) { String str1 = "hello world"; String str2 = new String(str1); if(str1==str2) System.out.println("str1==str2"); else System.out.println("str1!=str2"); if(str1.equals(str2)) System.out.println("str1 equals str2"); else System.out.println("str1 not equals str2"); } }
运行结果:
str1!=str2
str1 equals str2
这是由于str1和str2引用了两个”hello world”对象
字符串缓冲池
程序运行的时候会创建一个字符串缓冲池,当使用str2=”hello world”创建字符串的时候,程序首先会在字符串缓冲池中寻找相同值对象。第一个程序中,str1先被放到了缓冲池中。所以str2被创建的时候,程序找到了具有相同值的str1,将str1的引用指向了str2。
第二段程序中,使用了new操作符,明白的告诉程序:“我要一个新的对象”于是创建了一个新的”hello world”对象,他们的值相同,但位置不同。
第三段程序:
1 package com.fwj.teststring; 2 3 public class TestString { 4 5 public static void main(String[] args) { 6 7 String str1 = "hello world"; 8 String str2 = new String(str1); 9 str2 = str2.intern(); 10 if(str1==str2) 11 System.out.println("str1==str2"); 12 else 13 System.out.println("str1!=str2"); 14 if(str1.equals(str2)) 15 System.out.println("str1 equals str2"); 16 else 17 System.out.println("str1 not equals str2"); 18 } 19 20 }
运行结果:
str1==str2
str1 equals str2
这是由于String的intern()方法的返回值仍然是字符串,intern()方法检查字符串池里是否存在”hello world”这么一个字符串,如果存在,就返回字符串池里的字符串,如果不存在,该方法会把”hello world”添加到字符串缓冲池里,然后再返回它的引用。