Java面试题记录总结

此处记录做面试题时有疑惑的问题
参考面试题的网址

一、String相关的面试题

剖析String的底层原理的一些面试题解答
1、String创建几个对象的问题
知识点:字符串常量池,JVM中有一个字符串常量池,用来保存被共享的String对象,如果使用相同的字符串,首先去常量池中找,如果存在,不再创建新的对象,直接返回已存在对象的引用:如果不存在,才创建这个对象,并放入字符串常量池中,再返回其引用。String类是final的,是不可变类,可以调用intern()方法访问字符串池

  • String str="aaa";创建了几个对象?
    1个。String str只定义了一个名为str的String类型的变量,没有创建对象;=是对str变量的赋值;"aaa"创建了一个aaa对象,放入了字符串常量池中。
  • String str1="aaa"; String str2="aaa";创建了几个对象?
    1个。只创建了一个aaa对象,对str2赋值时,在字符串常量池中找到了aaa对象,直接使用。
  • String str=new String("abc");
    2个。一个abc对象,放在字符串池中,一个new String()对象,用来引用常量池中的对象
  • String a="ab"+"cd";
    1个。只创建一个abcd对象,ab、cd最终是没有被使用的,在jdk1.8之后,JVM内部,会将程序简化为:String a = “abcd”
  • String str1 = "abc"; String str2 = "ab"; String str3 = str2 + "c"; System.out.println(str1 == str3); //false
    String str3 = str2 + "c"涉及到了变量的相加,不全是常量,比如"ab"+"cd"其内部的实现是:先new一个StringBuffer,然后调用append方法,append(str)、append(“c”),最后再让str3调用toString返回对象。

网上对于这道题目的说法有很多种,如果各位大佬觉得我写的有问题,麻烦帮我指出来,非常感谢!

二、克隆问题

1、定义:克隆是对一个对象进行复制

2、为什么要克隆?为什么不直接new?
克隆的对象可能包含一些已经修改过的属性,而new出来的对象的属性都还是初始化时候的值,所以当需要一个新的对象来保存当前对象的“状态”就靠clone方法了。

注意:常见的Object a=new Object();Object b;b=a;这是对引用进行复制,即对象在内存中的地址,a和b对象仍然指向了同一个对象
而通过clone方法赋值的对象跟原来的对象时同时独立存在的。

3、实现:浅克隆(ShallowClone)和深克隆(DeepClone)

  • 浅克隆
  1. 被克隆的类需要实现Cloneable接口
  2. 覆盖clone()方法,访问修饰符设为public方法,方法中调用super.clone()方法得到需要的复制对象
class Student implements Cloneable{  //关键点1
    private int number;  
  
    public int getNumber() {  
        return number;  
    }  
  
    public void setNumber(int number) {  
        this.number = number;  
    }  
      
    @Override  
    public Object clone() {  
        Student stu = null;  
        try{  
            stu = (Student)super.clone();  //关键点2
        }catch(CloneNotSupportedException e) {  
            e.printStackTrace();  
        }  
        return stu;  
    }  
}  
public class Test {  
    public static void main(String args[]) {  
        Student stu1 = new Student();  
        stu1.setNumber(12345);  
        Student stu2 = (Student)stu1.clone();  //关键点3
          
        System.out.println("学生1:" + stu1.getNumber());  
        System.out.println("学生2:" + stu2.getNumber());  
          
        stu2.setNumber(54321);  
      
        System.out.println("学生1:" + stu1.getNumber());  
        System.out.println("学生2:" + stu2.getNumber());  
    }  
}
System.out.println(stu1 == stu2); // false  说明这两个不是同一个对象

在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址
在这里插入图片描述
简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。 在Java语言中,通过覆盖Object类的**clone()**方法可以实现浅克隆。

  • 深克隆

在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
在这里插入图片描述

在Java语言中,如果需要实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。

4、序列化
如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。

序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。

5、总结实现对象克隆有两种方式:

1. 实现Cloneable接口并重写Object类中的clone()方法;
2. 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。

参考链接

未完待续…

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值