程序猿的日常——Java基础之clone、序列化、字符串、数组
其实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方法 -- 原型模式
序列化与反序列化
序列化就是把对象形成字节流,反序列化就是通过字节流创建对象。它主要用于两个场景:
- 对象的持久化
- 对象的网络传输
实现起来很简单,只要实现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
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释