@TryLoveCatch
2022-04-14T08:47:18.000000Z
字数 5998
阅读 855
Java知识体系

public final native Class<?> getClass();
这是一个 final 类型的native方法,也就是说这个方法不能被子类重写,同时它的实现并不是通过Java语言实现的,而是用其他语言(C/C++)实现的,一般主要用在反射里面。
由于设计到JNI,所以这个方法是有一定耗时的是,使用的时候需要注意,还就是,toString()就使用了该方法。
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}
返回一个 String 对象,一般子类都有覆盖。默认返回格式如下:对象的 class 名称 + @ + hashCode 的十六进制字符串。
调用到的方法:
public native int hashCode();public boolean equals(Object obj) {return (this == obj);}
考虑一下HashMap,其实就是先判断hashCode再判断equals。
除了遵循这三原则之外,还要遵循:
关于相应的哈希算法,一个简单的算法如下:
组合公式:result = 31 * result + c
比如,String 类的 hashCode 方法如下(JDK 1.8):
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;}
class Baz {private int id;private String name;private double weight;private float height;private String note;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Baz baz = (Baz) o;if (id != baz.id) return false;if (Double.compare(baz.weight, weight) != 0) return false;if (Float.compare(baz.height, height) != 0) return false;if (name != null ? !name.equals(baz.name) : baz.name != null) return false;return !(note != null ? !note.equals(baz.note) : baz.note != null);}@Overridepublic int hashCode() {int result;long temp;result = id;result = 31 * result + (name != null ? name.hashCode() : 0);temp = Double.doubleToLongBits(weight);result = 31 * result + (int) (temp ^ (temp >>> 32));result = 31 * result + (height != +0.0f ? Float.floatToIntBits(height) : 0);result = 31 * result + (note != null ? note.hashCode() : 0);return result;}}
protected native Object clone() throws CloneNotSupportedException;
目的是想要两个相同的对象,重新new一个还得自己重新赋值,太麻烦
举个例子,一个男孩拥有一台电脑
- 需要拷贝的对象(Student)实现Cloneable接口
- 重写clone()方法
- 访问修饰符修改为public
- 通过super.clone()调用Object类中的原clone方法。
public class Student implements Cloneable {private String name;private Bag bag;public Student(String name,Bag bag) {this.name = name;this.bag = bag;}@Overridepublic Student clone(){Student stu = null;try{stu = (Student)super.clone();} catch (CloneNotSupportedException e){e.printStackTrace();}return stu;}}//背包类public class Bag {private String name;public void setName(String name) {this.name = name;}}
- 需要拷贝的对象(Student)以及其所有的对象成员变量(Bag)实现Cloneable接口
- 重写clone()方法
- 访问修饰符修改为public
- 通过super.clone()调用Object类中的原clone方法。
- 对于成员变量,都调用其重写的clone()方法
public class Student implements Cloneable {private String name;private Bag bag;public Student(String name,Bag bag) {this.name = name;this.bag = bag;}// 这里不一样!!!!!@Overridepublic Student clone(){Student stu = null;try{//浅克隆stu = (Student)super.clone();} catch (CloneNotSupportedException e){e.printStackTrace();}//深克隆stu.bag = (Bag)bag.clone();return stu;}}//背包类public class Bag {private String name;public Bag(String name) {this.name = name;}// 这里不一样!!!!!@Overridepublic Bag clone(){Bag bag= null;try{bag= (Bag )super.clone();} catch (CloneNotSupportedException e){e.printStackTrace();}return bag;}}
- 需要拷贝的对象(Student)实现Serializable接口
- 在需要拷贝的对象(Student)里面增加新方法,例如myClone()
- 通过ObjectOutputStream和ObjectInputStream序列化和反序列化获取到新的对象
// 这里不一样!!!!!public class Student implements Serializable {private String name;private Bag bag;public Student(String name,Bag bag) {this.name = name;this.bag = bag;}// 这里不一样!!!!!public Student myClone(){Student stu = null;try {//将对象序列化到流里ByteArrayOutputStream os = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(os);oos.writeObject(this);//将流反序列化成对象ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());ObjectInputStream ois = new ObjectInputStream(is);stu = (Student) ois.readObject();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return stu;}}// 这里不一样!!!!!public class Bag implements Serializable {private String name;public Bag(String name) {this.name = name;}}
如果某个属性被transient修饰,那么该属性就无法被拷贝了。
protected void finalize() throws Throwable { }
finalize()方法是保护方法,主要用于在 GC 的时候再次被调用,如果我们实现了这个方法,对象可能在这个方法中再次复活,从而避免被 GC 回收。
public final native void notify();public final native void notifyAll();public final native void wait(long timeout) throws InterruptedException;public final void wait() throws InterruptedException {wait(0);}
都是final方法,不能被子类重写。
https://www.sczyh30.com/posts/Java/java-hashcode-equal/
https://zhuanlan.zhihu.com/p/41880899