java修炼指南-读书笔记

重写equals方法

对于使用instanceof和getClass()运算符有如下建议:
1)如果子类能够拥有自身相等的概念,则对称性需求将强制采用getClass进行检测。
2)如果有超类决定相等的概念,那么就可以使用instanceof进行检测,这样可以在不同子类的对象之间进行相等的比较。

一个完美的equals方法重写

1)显示参数命名为otherObject,稍后会将它转换成另一个称为other的变量。
2)判断比较的两个对象引用是否相等,如果引用相等则表示是同一个对象。
3)如果otherObject为null,则直接返回false,表示不相等。比较this和otherObject是否是同一个类:
如果equals的语义在每个子类中有所改变,就使用getClass检测;如果所有的子类都有统一的定义,那么使用instanceof检测。
4)将otherObject转换成对应的类型变量。
5)最后对对象的属性进行比较。使用 == 比较基本类型,使用equals比较对象。如果都相等则返回true,否则返回false。注意如果是在子类中定义equals,则要包含super. equals(other)。

hashCode

当集合要添加新的元素时,先调用这个元素的hashCode方法,就能定位到它应该放置的物理位置上
当定位到的位置已经有元素时,调用equals方法判断元素是否一样,如果是一样则表示已经存在该元素
则将新的元素插入到已有元素的后面

创建对象的5种方式

1.new
2.通过Class类的newInstance()方法
Person p2 =Class.forName("com.kkb.tz.bean.Person").newInstance();
3.通过Constructor类的newInstance方法
Person p3 = Person.class.getConstructors()[0].newInstance();
4.使用clone方法
Person p4=(Person)p3.clone();
5.反序列化

基本类型和引用类型

深拷贝和浅拷贝

1.浅拷贝:直接实现clone接口,然后重写clone方法
2.深拷贝:
在clone方法中对引用类型做复制操作
利用序列化和反序列化,
如果有某个属性不需要序列化,可以将其声明为transient,即将其排除在克隆属性之外

String的数组

虽然String中的数组是final修饰的,只能保证引用是不可变的,如果有方法能够改变数组的值,依旧能改变数据
可以通过反射将字符串的内容改变
eg:

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        String str = "vae";
        System.out.println(str);
        Field fieldStr =  String.class.getDeclaredField("value");
        fieldStr.setAccessible(true);
        char[] value = (char[]) fieldStr.get(str);
        value[0]='a';
        System.out.println(str);
    }

一般很少会用反射去修改字符串的值,所以一般是认为字符串是不可变的
hashCode,当String被创建出来的时候,hashCode也会随之被缓存,hashCode的计算与value有关,若String可变,那么hashCode也会随之变化,针对Map、Set等容器,它们的键值需要保证唯一性和一致性,因此,String的不可变性使其比其他对象更适合当容器的键值

posted @ 2021-08-24 17:24  余***龙  阅读(85)  评论(0编辑  收藏  举报