四、基础 补充

96 阅读3分钟

一、 Cloneable 和 clone()

1.1 Cloneable 的用途

Cloneable和Serializable一样都是标记型接口,它们内部都没有方法和属性,implements Cloneable表示该对象能被克隆,能使用Object.clone()方法。如果没有implements Cloneable的类调用Object.clone()方法就会抛出CloneNotSupportedException。

1.2 克隆的分类

  1. 浅克隆(shallow clone),浅拷贝是指拷贝对象时仅仅拷贝对象本身和对象中的基本变量,而不拷贝对象包含的引用指向的对象。
  2. 深克隆(deep clone),深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。

举例区别一下:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2中包含对C2(C1的copy)的引用。

1.3 浅克隆和深克隆有什么区别?

区别主要在对引用类型的复制上,具体信息如下:

  • 浅克隆:只会复制对象的值类型,而不会复制对象的引用类型;
  • 深克隆:复制整个对象,包含值类型和引用类型。

1.4 如何实现克隆?

浅克隆:克隆的对象实现 Cloneable 接口,并重写 clone() 方法就可以实现浅克隆了。

深克隆:

  • 通过序列化实现深克隆(序列化实现方式:Java 原生序列化、JSON 序列化、Hessian 序列化);
  • 所有引用类型都实现克隆,从而实现深克隆。

为什么不能直接使用 Object 的 Clone 方法,还要重写 clone() 方法之后才能实现克隆?

虽然所有类都是 Object 的子类,但因为 Object 中的 clone() 方法被声明为 protected 访问级别,所以非 java.lang 包下的其他类是不能直接使用的。因此要想实现克隆功能,就必须实现 Cloneable,并重写 clone() 方法才行。

二、final 有什么用?

用于修饰类、属性和方法;

被final修饰的类不可以被继承;

被final修饰的方法不可以被重写;

被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的

三、static存在的主要意义

static的主要意义是在于创建独立于具体对象的域变量或者方法。以致于即使没有创建对象,也能使用属性和调用方法!

它的特性:只会在类加载的时候 执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。 例如:单例模式

四、Java 序列化中如果有些字段不想进行序列化怎么办

transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化。transient 只能修饰变量,不能修饰类和方法。

五、为什么 Java 中只有值传递?

Java 中没有实现引用传递,而是实现了值传递。这是因为 Java 中所有的参数都是对象的引用,而不是真正的对象。当调用方法时,实际上是传递了对象引用的副本,这就相当于值传递。因此,如果在方法内部修改引用,这些修改不会影响到原始引用,并且对原始对象的任何修改也不会影响到方法内部的引用。这是 Java 的设计选择,目的是保证程序的安全性和稳定性。