1. final关键字
可以用来修饰类、方法、变量。
修饰类表明这个类不可被继承
修饰方法表示这个方法不能被重写
修饰变量表示这个变量不能被修改
这里需要注意String类为final类,不可被继承大家都明白,但是String变量是不是可以被修改的呢?答案是否定的,原因:存储字符的数字是final类型的。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
String a = new String(“abc”);
String b = “abc”;
System.out.println(a==b);
结果为false。
但是
String a = “abc”;
String b = “abc”;
System.out.println(a==b);
结果为true。
结论:jvm会在内存中维持一个字符常量缓存区,在定义字符变量时候首先会到字符常量缓存区中查找是否有需要的对象。而new String()的方式,则会生成一个对象放到堆区。
其次,a+”a”会生成一个新的String对象。
2.深拷贝
需求场景;Object a = new Object(“abc”);
Object b =a;
则b对象指向a对象,对b对象的修改,都会反映到a对象上。如何才能让b完全实现a的拷贝呢?
深拷贝 ;
a:实现cloneable接口
b.重写clone()方法,这里必须有super.clone()调用,代表调用Object类的clone()方法。super.clone()即代表浅拷贝的意思,会把当前类从内存中复制一份,但是类的成员变量都是引用,除了基本数据类型(int,double等),注意String,Integer类型的变量也会是浅拷贝,不过没关系,因为它们在内存中是final类型的,如果修改它们的值会重新生成一个变量来替换,变相的达到了深度拷贝的功能。
```
public class User implements Cloneable {
private String userName;
private String passWord;
private Integer age;
public User next;
……
@Override
protected User clone() {
User u = null;
try {
u = (User)super.clone();
if (next != null) {
u.next = next.clone();
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return u;
}
}
只有加上u.next = next.clone();这行代码,才能实现next对象的拷贝,否则也只能是浅拷贝。
>序列化;如果不希望指定成员被序列化,添加修饰符transient即可,同时序列化的类必须实现Serializable接口
class Professor implements Serializable {
String name;
Integer age;
Professor(String name,int age){
this.name=name;
this.age=age;
}
class Student implements Serializable {
String name;
Integer age;
Professor p;
Student(String name, Integer age, Professor p) {
this.name = name;
this.age = age;
this.p = p;
}`
public Object deepClone() throws IOException, OptionalDataException, ClassNotFoundException {
//将对象写到流里
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(this);
//从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}
}