1.==和equals的区别
对于基本数据类型来说,==比较的是值。
对于引用数据类型来说,==比较的是对象的内存地址。
equals不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。(equals方法存在于Object类中,而Object类是所有类的直接或间接父类)
equals方法存在两种使用情况:
-
类没有覆盖 equals方法 :通过equals比较该类的两个对象时,比较的是两个对象的内存地址,等价于通过“==”比较这两个对象,使用的默认是 Object类equals方法。
-
类覆盖了 equals方法 :一般我们都覆盖equals方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。
2.为什么重写 equals 方法时必须重写 hashCode 方法?
如果两个对象相等,则它们的 hashcode 一定也是相同的。两个对象相等,对两个对象分别调用 equals 方法都返回 true。但是,两个对象有相同的 hashcode 值,它们也不一定是相等的 。因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖。
hashCode()的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。
3.为什么两个对象有相同的 hashcode 值,它们也不一定是相等的?
因为 hashCode() 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓碰撞也就是指的是不同的对象得到相同的 hashCode )。
4.常量池
Java 基本类型的包装类的大部分都实现了常量池技术。Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character 创建了数值在[0,127]范围的缓存数据,Boolean 直接返回 True/False。
两种浮点数类型的包装类 Float,Double 并没有实现常量池技术。
如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。
所有整型包装类对象之间值的比较,全部使用 equals 方法比较。
5.重载和重写的区别
- 重载发生在同一个类中(或者父类和子类之间),方法名必须相同,参数类型不同、个数不同、顺序不同,方法返回值和访问修饰符可以不同。
- 重写发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。 返回值类型、方法名、参数列表必须相同,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。 如果父类方法访问修饰符为 private/final/static 则子类就不能重写该方法,但是被 static 修饰的方法能够被再次声明。 构造方法无法被重写。
区别点 | 重载方法 | 重写方法 |
发生范围 | 同一个类 | 子类 |
参数列表 | 必须修改 | 一定不能修改 |
返回类型 | 可修改 | 子类方法返回值类型应比父类方法返回值类型更小或相等 |
异常 | 可修改 | 子类方法声明抛出的异常类应比父类方法声明抛出的异常类更小或相等 |
访问修饰符 | 可修改 | 一定不能做更严格的限制(可以降低限制) |
发生阶段 | 编译期 | 运行期 |