其实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));
}
序列化与反序列化
序列化就是把对象形成字节流,反序列化就是通过字节流创建对象。它主要用于两个场景:
对象的持久化
对象的网络传输
实现起来很简单,只要实现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, 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数组
关于数组,就有一个比较有意思的问题——数组是对象么?其实在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