缓存池
new Integer(123) 与 Integer.valueOf(123) 的区别在于:
new Integer(123) 每次都会新建一个对象;
Integer.valueOf(123) 会使用缓存池中的对象,多次调用会取得同一个对象的引用。
EG:
Integer x = new Integer(123);
Integer y = new Integer(123);
System.out.println(x == y); // false
Integer z = Integer.valueOf(123);
Integer k = Integer.valueOf(123);
System.out.println(z == k); // true
Integer m = Integer.valueOf(9999);
Integer n = Integer.valueOf(9999);
System.out.println(m == n); // false
SourceCode:
valueOf() 方法的实现比较简单,就是先判断值是否在缓存池中,如果在的话就直接返回缓存池的内容
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);
在 Java 8 中,Integer 缓存池的大小默认为 -128~127。
Others:
基本类型对应的缓冲池如下:
boolean values true and false
all byte values
short values between -128 and 127
int values between -128 and 127
char in the range u0000 to u007F
String Pool
字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。不仅如
此,还可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中。
当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法 进行确定),那么就会返回 String Pool 中字符串的引用;
否则,就会在 String Pool 中添加一个新的字符串,并返回 这个新字符串的引用。
new String("abc")
使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 "abc" 字符串对象)。
"abc" 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 "abc" 字符串字面 量;
而使用 new 的方式会在堆中创建一个字符串对象。
参数传递
Java 的参数是以值传递的形式传入方法中,而不是引用传递。
访问控制:
private protected public
作用于类:其它类是否可以用这个类创建实例对象。
作用于属性/方法:其它类可以用这个类的实例对象访问到该成员;
private和public两者都可修饰,protected只在修饰属性方法时有意义,表示是否可以在子类中访问
如果子类的方法重写了父类的方法,那么子类中该方法的访问级别不允许低于父类的访问级别。这是为了确保可以使 用父类实例的地方都可以使用子类实例,也就是确保满足里氏替换原则。
1. 重写(Override) 存在于继承体系中,指子类实现了一个与父类在方法声明上完全相同的一个方法。 为了满足里式替换原则,重写有以下三个限制:
子类方法的访问权限必须大于等于父类方法;
子类方法的返回类型必须是父类方法返回类型或为其子类型;
子类方法抛出的异常类型必须是父类抛出异常类型或为其子类型。
2. 重载(Overload) 存在于同一个类中,指一个方法与已经存在的方法名称上相同,但是参数类型、个数、顺序至少有一个不同。 应该注意的是,返回值不同,其它都相同不算是重载。
抽象类:
包含抽象方法的类
接口:
接口的成员(字段 + 方法)默认都是 public 的,并且不允许定义为 private 或者 protected。 接口的字段默认都是 static 和 final 的。
public native int hashCode() public boolean equals(Object obj) protected native Object clone() throws CloneNotSupportedException public String toString() public final native Class<?> getClass()
equals()
检查是否为同一个对象的引用,如果是直接返回 true;
检查是否是同一个类型,如果不是,直接返回 false;、
将 Object 对象进行转型;
判断每个关键域是否相等。
hashCode()
hashCode() 返回散列值,相等的两个对象的散列值一定相同,所以如果我们重写equals方法,也要重写hashcode方法,继续上面的重写hashcode
clone()
首先:clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写 clone(),其它类就不能直接去调用该类实例的 clone() 方法。
其次:java规定clone() 要和 cloneable一起使用,也就是先继承cloneable方法再去重写clone()
final:
1. 数据
声明数据为常量,可以是编译时常量,也可以是在运行时被初始化后不能被改变的常量。
对于基本类型,final 使数值不变;
对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
2. 方法
声明方法不能被子类重写。
private 方法隐式地被指定为 final,如果在子类中定义的方法和基类中的一个 private 方法签名相同,此时子类的方 法不是重写基类方法,而是在子类中定义了一个新的方法。
3. 类
声明类不允许被继承。
static
1. 静态变量
静态变量:又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,可以直接通过类名来 访问它。静态变量在内存中只存在一份。
实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。
2. 静态方法
静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实现,也就是说它不能是抽象方法。