Java学习(十一)
目录:
1、标记接口:
2、CloneNotSupportedException异常:
3、浅克隆与深克隆:
4、clone方法被设置为protected:
5、代码示例:
6、命令行编译时出现了“编码GBK的不可映射字符“的错误:
1、标记接口:
答:一个带空体的接口成为标记接口(marker interface)。一个标记接口既不包括常量也不包括方法。它表示一个类拥有某些特定的属性。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用在Object类中定义的clone()方法克隆。
2、CloneNotSupportedException异常:
答:如果一个类没有实现自己的clone方法,该类的实例调用的是Object.clone()方法,当调用到了Object.clone()方法时,会抛出CloneNotSupportedException异常。该异常指示不能或不应复制一个对象。
图2.1 报错截图
3、浅克隆与深克隆:
答:深克隆:深克隆拷贝对象本身,也拷贝对象包含的引用指向的所有的对象。
浅克隆:浅克隆指拷贝对象本身和拷贝对象中的基本变量,而不拷贝对象包含的引用指向的对象。
4、clone方法被设置为protected:
答:因为克隆可能引起问题,例如当一个对象打开了一个I/O流并被克隆,两个对象可以操作相同的流。当其中一个对象关闭了流,而另一个对象仍试图对I/O流进行写操作的话,将导致错误。因此它必须由实现了Cloneable类定义的方法调用,或者被显式重载。
5、代码示例:
①实体类IDCard.java
package com.remoa.IdCard.domain;
public class IDCard {
private String nativePlace;
private String sex;
private String birthday;
public IDCard(String nativePlace, String sex, String birthday){
this.nativePlace = nativePlace;
this.sex = sex;
this.birthday = birthday;
}
public String getNativePlace() {
return nativePlace;
}
public void setNativePlace(String nativePlace) {
this.nativePlace = nativePlace;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "IDCard [nativePlace=" + nativePlace + ", sex=" + sex + ", birthday=" + birthday + "]";
}
}
package com.remoa.User.domain;
import java.sql.Date;
import java.text.SimpleDateFormat;
import com.remoa.IdCard.domain.IDCard;
public class User implements Cloneable{
private int id;
private String name;
private IDCard idCard;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IDCard getIdCard() {
return idCard;
}
public void setIdCard(IDCard idCard) {
this.idCard = idCard;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", idCard=" + idCard + "]";
}
public User clone() throws CloneNotSupportedException{
return (User)super.clone();
}
@SuppressWarnings("deprecation")
public static void main(String[] args) throws CloneNotSupportedException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
User user1 = new User();
user1.setId(5847);
user1.setName("Remoa");
user1.setIdCard(new IDCard("广州", "男", sdf.format(new Date(1996 - 1900, 9 - 1, 1))));
User user2 = user1.clone();
System.out.println(user1 == user2);//false,说明指向的不是同一个对象
System.out.println(user1.equals(user2));//false
System.out.println(user2.getClass());//class com.remoa.learn.User
System.out.println(user1.getClass().equals(user2.getClass()));//true
System.out.println("user1的hashCode为:" +user1.hashCode());//user1的hashCode为:1956725890
System.out.println("user2的hashCode为:" +user2.hashCode());//user2的hashCode为:356573597
System.out.println("user1的内容为:" + user1);//user1的内容为:User [id=5847, name=Remoa, idCard=IDCard [nativePlace=广州, sex=男, birthday=1996-09-01]]
System.out.println("user2的内容为:" + user2);//user2的内容为:User [id=5847, name=Remoa, idCard=IDCard [nativePlace=广州, sex=男, birthday=1996-09-01]]
user2.setIdCard(new IDCard("深圳", "女", sdf.format(new Date(1997 - 1900, 12 - 1, 15))));
System.out.println("----------对user2进行修改-------------------");
System.out.println("user1的内容为:" + user1);
System.out.println("user2的内容为:" + user2);
}
}
运行结果:
图5.1 运行结果截图1
③实体类User2.java
package com.remoa.User.domain;
import java.sql.Date;
import java.text.SimpleDateFormat;
import com.remoa.IdCard.domain.IDCard;
public class User2 {
private int id;
private String name;
private IDCard idCard;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public IDCard getIdCard() {
return idCard;
}
public void setIdCard(IDCard idCard) {
this.idCard = idCard;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", idCard=" + idCard + "]";
}
@SuppressWarnings("deprecation")
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
User2 user1 = new User2();
user1.setId(5846);
user1.setName("Cui");
user1.setIdCard(new IDCard("广州", "男", sdf.format(new Date(1996 - 1900, 9 - 1, 1))));
User2 user2 = user1;
System.out.println(user1 == user2);//true,说明两个对象的引用指向的是同一块内存空间,同一个对象
System.out.println(user1.equals(user2));//true,比较的是对象的值
System.out.println(user1.getClass());//class com.remoa.learn.User2
System.out.println(user1.getClass() == user2.getClass());//true,同一个类型的Class
System.out.println("user1的hashCode为:" +user1.hashCode());//user1的hashCode为:1956725890
System.out.println("user2的hashCode为:" +user2.hashCode());//user2的hashCode为:1956725890
System.out.println("user1的内容为:" + user1);//user1的内容为:User [id=5846, name=Cui, idCard=IDCard [nativePlace=广州, sex=男, birthday=1996-09-01]]
System.out.println("user2的内容为:" + user2);//user2的内容为:User [id=5846, name=Cui, idCard=IDCard [nativePlace=广州, sex=男, birthday=1996-09-01]]
user2.setIdCard(new IDCard("深圳", "女", sdf.format(new Date(1997 - 1900, 12 - 1, 15))));
System.out.println("----------对user2进行修改-------------------");
System.out.println("user1的内容为:" + user1);//user1的内容为:User [id=5846, name=Cui, idCard=IDCard [nativePlace=深圳, sex=女, birthday=1997-12-15]]
System.out.println("user2的内容为:" + user2);//user2的内容为:User [id=5846, name=Cui, idCard=IDCard [nativePlace=深圳, sex=女, birthday=1997-12-15]]
}
}
运行结果:
6、命令行编译时出现了“编码GBK的不可映射字符“的错误:
答:解决办法: javac --encoding utf-8 User.java