1.JAVA虚拟机存储空间分布图:
常量池是一个与Heap和Stack并列的存储区,存在于Method Area中。常量池存放字符串常量和基本数据类型常量。如果一个字符串在编译期已经创建好("")则存储在常量池中,如果是运行期(new)才能确定的则存储在堆中。
堆中存放运行时的对象。
栈中存放对象的引用、基本数据类型的变量以及运行时的方法。
2.hashCode()和equals()的隐式调用约定:
如果两个对象相等(equal),那么他们一定有相同的哈希值。
如果两个对象有相同的哈希值,他们未必相等(equal)。
一般来说Object类默认的equals()同于==,即比较堆内存中的存放地址。但是在String,Integer,Date等类中覆写了这个方法,有了其自身的实现。比如在String中的equals就是比较字符串的内容是否相等。
这条约定可以应用于Map<Key,Value>的存取当中。下面给出一个例子:
import java.util.HashMap;
public class Ball {
// this表示对当前对象的引用
private String color;
public Ball(String color) {
this.color = color;
}
public static void main(String[] args) {
Ball b1 = new Ball("red");
Ball b2 = new Ball("green");
HashMap<Ball, String> map = new HashMap<Ball, String>();
map.put(b1, "10");
map.put(b2, "20");
System.out.println("从map中取出key为<颜色是green的Ball>的String值>" +map.get(new Ball("red")));
}
}
首先介绍一下Map的存取机制:Map内部有一个顶层数组,首先通过Key对象的hashCode()计算出顶层数组通往第二层数组的索引,通过这个索引找到第二层数组,在第二层数组中使用equals()判断是否存在key键对应的value值。
Object类中默认的hashCode()是让每个对象都返回一个不用的int值,所以上述代码一定会返回null。那么如何通过上述代码获取Map中以颜色是red的Ball对象为key的Value值(在获取时不要求key键的对象与存储时的对象是同一个对象,只要求对象中的颜色字段相等)?我们要覆写一下hashCode()和equals()方法。
首先是equals():当对象引用指向的是Ball的对象并且该对象的color字段相等时,我们就判定为true。
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Ball)) {
return false;
}
return this.color == ((Ball) obj).color;
}
其次是hashCode():返回Ball类对象的color字段字符串的长度。
@Override
public int hashCode() {
return this.color.length();
}
看下这样是否符合开始说的约定:equals返回true时hashCode一定相等,hashCode相等时equals不一定返回true。很明显这符合约定。再次运行一下程序,发现果然成功取出了value值("10")。下面给出我理解中的Map查询机制图:
4.OO的概念和设计原则(面向对象):使用类和继承的构造机制,拥有继承、封装、多态等几大特性。
5.this的用法:
表示对当前对象的引用。
区分类的成员变量和函数的参数(本质上同上一点)。
在构造方法中引用自身满足参数类型的构造器。