1. getClass方法public final native Class<?> getClass();
getClass方法返回对象运行时的类,即返回的是动态类型的类
Java不是存粹的静态类型或者动态类型,A a,A就是静态类型,若B继承于A,a = new B(),B就是动态类型。
可以通过以下例子看出getClass方法的返回。。
A a = new A();
A b = new B();
B c = new B();
System.out.println(a.getClass().getName());
System.out.println(b.getClass().getName());
System.out.println(c.getClass().getName());
//结果如下:
test.A
test.B
test.B
2. hashCode()方法
- hashCode方法返回对象的哈希值,它的存在是为了提高HashTable、HashMap等的效率。
重写hashCode的原则 - 对于同一对象,在不改变equals方法前提下,必须返回相同的哈希值。
- 对于equals方法返回true的两个对象,哈希值必须返回相同的。
- 对于equals方法返回false的两个对象,哈希值可以相同也可以不相同,但是我们应该尽量让他们的哈希值不相同。
3. equals()方法
比较两个对象的相等性,是比较的是两个对象的内存地址
其底层是使用了“==”来实现,
也就是说通过比较两个对象的内存地址是否相同判断是否是同一个对象。
public boolean equals(Object obj) {
return (this == obj);
}
Why重写equals方法必须重写hashCode()方法
先说为什么要重写equals方法?
因为equals底层实现是==来比较内存地址,但是在实际应用中,该方法不能满足的我们的需求。因为我们认为两个对象即使不是指向的同一块内存,只要这两个对象的各个字段属性值都相同,那么就认为这两个对象是同一个对象。所以就需要重写equals()方法,即如果两个对象指向内存地址相同或者两个对象各个字段值相同,那么就是同一个对象。
回到问题,为什么需要重写hashcode
- hashCode()方法是一个本地native方法,返回的是对象引用中存储的对象的内存地址
- 而equals方法是利用==来比较的也是对象的内存地址。
- 假设两个对象,重写了其equals方法,其相等条件是属性相等,就返回true。
- 如果不重写hashcode方法,其返回的依然是两个对象的内存地址值,必然不相等。
- 这就出现了equals方法相等,但是hashcode不相等的情况。这不符合hashcode的规则。
实际的意义
在Java中的一些容器(如:set)中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了equals()的方法,而不重写hashcode的方法,Object中hashcode是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashcode方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。
怎么重写两个方法
public class SimpleDemo {
// 部门
private String department;
// 工号
private int id;
public SimpleDemo(int id, String department) {
super();
this.id = id;
this.department = department;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getdepartment() {
return department;
}
public void setdepartment(String department) {
this.department = department;
}
@Override
public int hashCode() {
int hash = 1;
hash = hash * 17 + id;
hash = hash * 31 + department.hashCode();
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
//如果两个的参数什么都相同,即使是不同的对象也判断相等
if (obj instanceof SimpleDemo) {
SimpleDemo sd = (SimpleDemo) obj;
return sd.department.equals(department) && sd.id == id;
}
return false;
}
public class Test02 {
public static void main(String[] args) {
SimpleDemo sdo1=new SimpleDemo(0106,"技术部");
SimpleDemo sdo2=new SimpleDemo(0106,"技术部");
//print true
//重写后让参数相同的两个对象相等了
System.out.println(sdo1.equals(sdo2));
}
}
再说一些
一般String都是重写了equals方法的
String如何判断=
1. 对象是否相同,相同true
2. 长度是否相同
3. 遍历char数组,如果char数组每个元素都相同,判断true
//String重写的equals方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
//String重写的hashcode方法
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
4. clone()方法
clone方法返回一个对象的复制。使用克隆方法的类必须实现Cloneable接口,否则会抛出CloneNotSupportedException异常。
protected native Object clone() throws CloneNotSupportedException;
5. ToString()方法
toString方法返回对象的字符串。如果我们自己的类没有重写toString方法,就会返回类名加类的哈希值的16进制的表示。
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
6. notify() 、notifyAll、wait、
7. finalize()
当垃圾回收器认为一个对象没有其他引用时,就调用finalize()方法清理对象。
protected void finalize() throws Throwable { }