java面向对象的特性:
(1)继承
(2)封装
(3)多态性:不同子类型对同一消息做出不同的相应。方法重载是编译时的多态性(前绑定),方法重写是运行时的多态性(后绑定)。
(4)抽象:
访问修饰符:
java对象clone()方法
java赋值是复制对象引用,如果我们想要得到一个对象的副本,使用赋值操作是无法达到目的的:
@Test
public void testassign(){
Person p1=new Person();
p1.setAge(31);
p1.setName("Peter");
Person p2=p1;
System.out.println(p1==p2);//true
}
最终还是同一个对象
如何进行对象克隆
Object对象有个clone()方法,实现了对象中各个属性的复制,但它的可见范围是protected的,所以实体类使用克隆的前提是:
① 实现Cloneable接口,这是一个标记接口,自身没有方法。
② 覆盖clone()方法,可见性提升为public。
@Data
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
@Test
public void testShallowCopy() throws Exception{
Person p1=new Person();
p1.setAge(31);
p1.setName("Peter");
Person p2=(Person) p1.clone();
System.out.println(p1==p2);//false
p2.setName("Jacky");
System.out.println("p1="+p1);//p1=Person [name=Peter, age=31]
System.out.println("p2="+p2);//p2=Person [name=Jacky, age=31]
}
为Person增加一个Address类的成员:
@Data
public class Address {
private String type;
private String value;
}
@Test
public void testShallowCopy() throws Exception{
Address address=new Address();
address.setType("Home");
address.setValue("北京");
Person p1=new Person();
p1.setAge(31);
p1.setName("Peter");
p1.setAddress(address);
Person p2=(Person) p1.clone();
System.out.println(p1==p2);//false
p2.getAddress().setType("Office");
System.out.println("p1="+p1);
System.out.println("p2="+p2);
}
输出:
false
p1=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
p2=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
遇到了点麻烦,只修改了p2的地址类型,两个地址类型都变成了Office。只修改 p2 的值会导致 p1 的值也进行了改变
浅拷贝:被复制对象的所有值属性都含有与原来对象的相同,而所有的对象引用属性仍然指向原来的对象。
深拷贝:在浅拷贝的基础上,所有引用其他对象的变量也进行了clone,并指向被复制过的新对象。
如果被复制对象的属性包含其他实体类对象引用,那么这些实体类对象都需要实现cloneable接口并覆盖clone()方法。
public class Address implements Cloneable {
private String type;
private String value;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
同时Person的clone还需要显示的clone其引用成员
public class Person implements Cloneable {
private String name;
private Integer age;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj=super.clone();
Address a=((Person)obj).getAddress();
((Person)obj).setAddress((Address) a.clone());
return obj;
}
}
最终结果:
false
p1=Person(name=Peter, age=31, address=Address(type=Home, value=北京))
p2=Person(name=Peter, age=31, address=Address(type=Office, value=北京))
这样当我们改变 p1 的值时才不会修改到 p2 的值
clone()与new的区别
clone()不会调用构造方法;new会调用构造方法
clone()更快。clone()能快速创建一个已有对象的副本,即创建对象并且将已有对象中所有属性值克隆;new只能在JVM中申请一个空的内存区域,对象的属性值要通过构造方法赋值
throw 与throws的区别
switch
java5以前switch(expr),expr中只能是byte,short,char,int。从5开始,java引入枚举类型。7开始可以使 String。但是long类型是不可以的。
equals与hashCode(用于对象的重写)
1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。(默认比较对应的地址)
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
https://blog.csdn.net/qq_33314107/article/details/80271963 (clone讲解)