1, What is clonable
Clonable is an interface of java. There is no method to be enforced in the interface. Therefore, this is a marked interface. When implementing this method, you should take the initiative to implement the clone method, otherwise you will throw a clonnotsupportedexception exception.
// BEGIN Android-changed: Use native local helper for clone() // Checks whether cloning is allowed before calling native local helper. // protected native Object clone() throws CloneNotSupportedException; protected Object clone() throws CloneNotSupportedException { if (!(this instanceof Cloneable)) { throw new CloneNotSupportedException("Class " + getClass().getName() + " doesn't implement Cloneable"); } return internalClone(); } /* * Native helper method for cloning. */ @FastNative private native Object internalClone(); // END Android-changed: Use native local helper for clone()
It can be seen from the source code that the internalClone method body is implemented in the native layer, and whether the clonable interface is implemented will be verified when calling the clone method
2, How are deep and shallow copies represented?
The difference between deep copy and shallow copy. I think it is the transfer of reference address or the real object copy. It is explained by code below.
public class Teacher implements Cloneable{ public String name; public int age; public Student student; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public class Student { public String name; public int age; }
Teacher teacher = new Teacher(); teacher.name="teacher"; teacher.age = 100; Student student = new Student(); student.name="student"; student.age=90; teacher.student = student; try { Teacher cloneTeacher = (Teacher) teacher.clone(); //The two hash values are different Log.e("teacher",teacher.hashCode()+" "+cloneTeacher.hashCode()); //Both hash values are the same Log.e("teacher",teacher.student.hashCode()+" "+cloneTeacher.student.hashCode()); } catch (CloneNotSupportedException e) { e.printStackTrace(); }
Through the log printing, it is found that a new object can be completely copied through the clone method. You can convert gson into json data to see that the attribute values of the two are the same. However, you will find that although the teacher and cloneTeacher are different objects, their students are the same object, because the hash values of the two are the same, You can also modify the name value of the student in cloneTeacher, and then print to see if the name value of the student in the teacher also changes. This is actually a shallow copy. It can be understood that the student object is not recreated, but the reference address still points to the original. The cloned teacher object shares the same student.
Next, let's try to modify the above code
public class Teacher implements Cloneable{ public String name; public int age; public Student student; @Override protected Object clone() throws CloneNotSupportedException { Teacher teacher = (Teacher) super.clone(); //Here, the student is deeply cloned teacher.student = (Student) student.clone(); return teacher; } }
public class Student implements Cloneable{ public String name; public int age; @Override protected Object clone() throws CloneNotSupportedException { //Because the teacher called the clone method on the student, it is necessary to rewrite the method and implement the Cloneable interface return super.clone(); } }
After the code is modified, perform the above log verification again
//The two hash values are different Log.e("teacher",teacher.hashCode()+" "+cloneTeacher.hashCode()); //The two hash values are different Log.e("teacher",teacher.student.hashCode()+" "+cloneTeacher.student.hashCode());
Therefore, it can be judged that the student objects of both at this time do not point to the same one, which is called deep copy.
Summary: if the clone object is only accessed, there is no difference between deep and shallow copy. However, once the attribute of the clone object is modified, this shallow copy method is very dangerous and affects the use of original data by other businesses. Therefore, in daily development, we should pay attention to using the deep copy method as much as possible. In the clone method, manually clone and assign the reference types in turn.