java基础题

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讲解)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值