1. Object类
Java作为单继承语言,Object类是所有的类的祖先,所有类在没有指定继承父类的情况下都是默认继承Object类中的方法。
Object类有12个成员方法,分别是(省略修饰符)String toString()、Object clone()、boolean equals(Object)、void finalize()、getClass() 、int hashCode()、void notify()、void notifyAll()、、 void wait()、void wait(long)、void wait(long,int)。
其中带有Native关键字的方法意味着其是被JVM(C++)通过底层语言执行。
1) public Object() : Object对象的无参构造方法
2) public String toString()
public String toString(){
return getClass().getName()+ '@' +Integer.toHexString(hasCode());
}
toString()方法返回代表该对象的一个字符串,默认的实现是获取该类的路径(getClass().getName())以及哈希散列值。通常需要在子类中重写hasCode方法。
3)public Native int hasCode()
返回当前对象的哈希值(物理地址),根据散列约定,如果两个对象相同,它们的散列码一定相同,因此如果在子类中重写了 equals 方法,必须在该子类中重写 hashCode 方法,以保证两个相等的对象对应的散列码是相同的。
两个相等的对象一定具有相同的散列码,两个不同的对象也可能具有相同的散列码。实现 hashCode 方法时,应避免过多地出现两个不同的对象也可能具有相同的散列码(哈希冲突)的情况。
4)public boolean equals(Object obj)
public boolean equals(Object obj){
return this == obj;
}
用于比较两者是否相等,对于基本数据类型比较值是否相等,对于引用数据类型比较地址是否相等,通常而言需要重写。
5)public void finalize() throws Throwable
finalize()方法用于垃圾回收,如果一个对象不再被访问,该对象被视为"垃圾",finalize方法会被该对象的垃圾回收程序(GC)调用。该方法的默认实现不做任何事,如果必要,子类应该重写该方法。该方法可能抛出Throwable异常。
6)protected native Object clone() throws CloneNotSupportedException
clone()方法用于该方法用于复制一个对象,以Object对象的形式创建并返回一个对象的拷贝。不是所有的对象都可以复制,只有当一个类实现了 java.lang.Cloneable 接口时,这个类的对象才能被复制。该方法可能抛出 CloneNotSupportedException 异常。
7)public final native Class<?> getClass()
该方法返回对象的元对象。元对象是一个包含类信息的对象,包括类名、构造方法和方法等。一个类只有一个元对象。每个对象都有一个元对象,同一个类的多个对象对应的元对象相同。
2. 基本类型与包装类型
Java提供的8种基本的数据类型每一个都对应了一个包装数据类型,包装类的名称和对应的基本数据类型相同,包装类的名称的首字母大写,Integer 和 Character 例外。基本数据类型与包装类型的区别如下:
1) 基本数据类型是变量,包装数据类型是引用
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
"=="对于基本数据类型比较的是值是否相等,对于包装类型(引用)比较的是地址是否相等;''.equals()"用于比较两个引用类型的值是否相等;
通常而言,基本数据类型比引用类型更高效,因为基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。
2)包装类型的值可以为null,基本数据类型不可以
数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出 NullPointerException
的异常。
3)包装类型可用于泛型,而基本类型不可以(会编译报错)
因为泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类——包装类型是个特例。
4)包装类型的装箱、拆箱
将基本数据类型转换为包装数据类型的过程称为装箱,将包装类型转换为基本数据类型的过程称为拆箱,在JDK1.5以后,以上过程就是自动实现的。
自动装箱:
· 在(-128~127)之内 调用相应包装类的valueOf():其实在该范围之内,源码底层中是通过数组 IntegerCache(Integer缓存池) 存的值,当在该范围内再一次定义相同大小的值,如12,JDK它会在相应的数组里找到该值是不是存在,如存在则数组里存有12,则把它的引用给该对象,所以它们的地址是相等的。
Integer i = 12;
Integer a = 23;
// 以上过程由JDK编译器自动完成的,即自动调用Integer.valueOf()方法
// 实际为
// Integer i = Integer.valueOf(12); Integer a = Integer.value(23);
· 不在(-128~127)之内 直接 new 对象:不在该范围内则通过 new 关键字在堆中创建相应的对象;注意:只要其基本数据类型值相同,则hasCode的值也相等。
Integer i = 200;
Integer a = 200;
/*
* 实际上为
* Integer i = new Integer(200);
* Integer a = new Integer(200);
*/
自动拆箱:
自动拆箱默认调用 .xxxValue()方法;注意:在包装类进行与基本数据类型比较时 ,会存在自动拆箱的操作。
Integer i = 100;
int a = i;
/* 实际上底层调用了相应的xxxValue()方法:
* Integer i = 100;
* int a = i.intValue();
*/
3. 包装类型常用方法
1. parseXXX(String s):将字符串转换为相应的基本数据类型(静态方法)。
底层调用的方法为parseXXX(String s, int raidx),将字符串转换为基本数据类型,静态方法。例如:Integer.parseInt(String s, int radix)
// 将字符串转换为基本数据类型
int i = Integer.parseInt("123");
注意:Character类型没有parseXXX()方法。
2. valueof(String s):将字符串转换为相应的包装类型(静态方法)
底层调用parseXXX(String s)方法,先将字符串转换为基本数据类型 ;再通过valueof(baseType i)将基本数据类型变量转换为包装类型(注意:Character类型不支持String转换),源码如下:
例如:Integer.valueof(String s):
// 将字符串转换为包装类型Integer
Integer i = Integer.valueof("123");
3. valueof(value):将基本数据类型转换为包装类型(静态方法,所有包装类型均支持)
底层源码:如果在Ingeter常量池中直接返回常量池引用,否则new一个Integer对象并通过基本类型值初始化,例如:Integer.valueof(int i)
// 将int类型变量转换为包装类型Integer
Integer i = Integer.valueof(123);
注意:JDK8以后就支持自动装箱了,即valueof(int i)是自动执行的,直接通过 Integer i = 123;实现即可。
4. XXXvalue():将包装类型转换为XXX基本数据类型(实例方法,所有包装类型均支持)
注意:JDK8以后就支持自动拆箱了,即intvalue()是自动执行的,直接通过 int num = i;实现即可,例如:i.intvalue();
// 将包装类型Integer转换为基本数据类型int
Integer i = 123;
int num = i.intValue();
5. toString(value):将基本数据类型转换为字符串(静态方法)