程序猿的日常——Java基础之clone、序列化、字符串、数组

时间:2022-04-22
本文章向大家介绍程序猿的日常——Java基础之clone、序列化、字符串、数组,主要内容包括深克隆与浅克隆、序列化与反序列化、String源码、Java数组、Java数据类型、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

其实Java还有很多其他的基础知识,在日常工作技术撕逼中也是经常被讨论的问题。

深克隆与浅克隆

在Java中创建对象有两种方式:

一种是new操作符,它创建了一个新的对象,并把对应的各个字段初始化成默认值;

另一种是用clone方法,基于已有的对象创建一个新的对象,此时会根据原有的对象各个字段赋值给新的对象。

如果对象的字段都是基础类型,没有什么问题,但是如果字段是对象,那么其实clone的时候复制的仅仅是对象的引用而已。

上面就是深克隆与浅克隆的区别。

在我们日常的开发中,如果涉及到克隆,就需要注意深克隆和浅克隆的区别。

如果想要实现深克隆,可以实现Cloneable接口,并且重写clone方法,然后一定要把涉及到深克隆问题的内部对象重新克隆一份。当然如果这个对象里面还有其他的对象,那么仍然是有问题的。

static class Body implements Cloneable{  
    public Head head;  
    public Body() {}  
    public Body(Head head) {this.head = head;}  
  
    @Override  
    protected Object clone() throws CloneNotSupportedException {  
        Body newBody =  (Body) super.clone();  
        newBody.head = (Head) head.clone();  
        return newBody;  
    }  
      
}  
static class Head implements Cloneable{  
    public  Face face;  
    public Head() {}  
    public Head(Face face){this.face = face;}  
    @Override  
    protected Object clone() throws CloneNotSupportedException {  
        return super.clone();  
    }  
}   
public static void main(String[] args) throws CloneNotSupportedException {  
    Body body = new Body(new Head());  
    Body body1 = (Body) body.clone();  
    System.out.println("body == body1 : " + (body == body1) );  
    System.out.println("body.head == body1.head : " +  (body.head == body1.head));  
}

参考 详解Java中的clone方法 -- 原型模式

序列化与反序列化

序列化就是把对象形成字节流,反序列化就是通过字节流创建对象。它主要用于两个场景:

  1. 对象的持久化
  2. 对象的网络传输

实现起来很简单,只要实现Serializable接口即可。

参考 对Java Serializable(序列化)的理解和总结

String源码

有一些Java经验的都应该了解,String字符串是不可变的,即:

String s1 = "123";
s1 = s1+"4";

其实他们俩是两个对象。这是因为在String代码中,有两个变量,char的value数组,和hash值,但是它俩都是private final类型,也就是说一旦创建就无法修改了。

public final class String  
    implements java.io.Serializable, Comparable<String>, CharSequence {  
    /** The value is used for character storage. */  
    private final char value[];  
  
    /** Cache the hash code for the string */  
    private int hash; // Default to 0  

而当调用各种substring,replaceall等方法的时候,其实也是创建了新的string对象。

不过它并非不可修改的,也可以通过反射的方式修改内容。

参考 Java中的String为什么是不可变的? -- String源码分析

Java数组

关于数组,就有一个比较有意思的问题——数组是对象么?其实在Java中所有的东西都是对象,都继承了Object类。只不过为了方便实用,有提供了Object[]的引用方法。

详细的可以参考这篇文章 Java数组特性

Java数据类型

Java包含了八种基本数据类型。六种数字类型,一种字符类型,一种Bool类型。

基本数据类型

包装数据类型

位数

最小值

最大值

默认值

byte

Byte

8位

-2^7

2^7-1

0

short

Short

16位

-2^15

2^15-1

0

int

Integer

32位

-2^31

2^31-1

0

long

Long

64位

-2^63

2^63-1

0L

float

Float

32位

1.4E-45

3.4028235E38

double

Double

64位

4.9E-324

1.7976931348623157E308

boolean

Boolean

1位

char

Char

16位

数据类型可以自动转换

低 ---------------------------------------------> 高

byte,short,char —> int —> long—> float —> double