|
| 1 | +> 我感觉这问题被问的频率有点高 |
| 2 | +
|
| 3 | +面试官:出个题: |
| 4 | + |
| 5 | +```java |
| 6 | +Integer a = new Integer(5); |
| 7 | +Integer b = new Integer(5); |
| 8 | +System.out.println(a == b); // false |
| 9 | +``` |
| 10 | + |
| 11 | +我:false,太简单了嘛。 == 比较的是两个对象的地址哦,你看: |
| 12 | + |
| 13 | +它的作用是**判断两个对象的地址是不是相等**。即,判断两个对象是不是同一个对象: |
| 14 | + |
| 15 | +- 基本数据类型==比较的是**值** |
| 16 | + |
| 17 | +- 引用数据类型==比较的是**内存地址** |
| 18 | + |
| 19 | +你要是:`System.out.println(a.equals(b)); \\ false` |
| 20 | + |
| 21 | +面试官:那这个呢: |
| 22 | + |
| 23 | +```java |
| 24 | +int a = 5; |
| 25 | +Integer b = new Integer(5); |
| 26 | +System.out.println(a == b); // true |
| 27 | +``` |
| 28 | + |
| 29 | +我:你想考我装箱拆箱嘛?其实,b看到了对面那个哥们是**基本类型**,我也是基本类型包装的呀,我把衣服一脱,那么就是**基本类型**了,那就是上面的结论了。b拆箱即可。 |
| 30 | + |
| 31 | +装箱:**自动将基本数据类型转换为包装器类型** |
| 32 | + |
| 33 | +拆箱:**自动将包装器类型转换为基本数据类型** |
| 34 | + |
| 35 | +基本类型有: |
| 36 | + |
| 37 | +- byte(1字节):Byte |
| 38 | +- short(2字节):Short |
| 39 | +- int(4字节):Integer |
| 40 | +- long(8字节):Long |
| 41 | +- float(4字节):Float |
| 42 | +- double(8字节):Double |
| 43 | +- char(2字节):Character |
| 44 | +- boolean(未知):Boolean |
| 45 | + |
| 46 | +**在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法** |
| 47 | + |
| 48 | +valueOf: |
| 49 | + |
| 50 | +```java |
| 51 | +public static Integer valueOf(int i) { |
| 52 | + if (i >= IntegerCache.low && i <= IntegerCache.high) |
| 53 | + return IntegerCache.cache[i + (-IntegerCache.low)]; |
| 54 | + return new Integer(i); |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +intValue: |
| 59 | + |
| 60 | +```java |
| 61 | +public int intValue() { |
| 62 | + return value; |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +面试官:聊一下equals |
| 67 | + |
| 68 | +我:equals是顶层父类Object的方法之一 |
| 69 | + |
| 70 | +```java |
| 71 | +// 你看,object默认调用的== , 你对象如果不重写,可能会发上重大事故 |
| 72 | +public boolean equals(Object obj) { |
| 73 | + return (this == obj); |
| 74 | +} |
| 75 | +``` |
| 76 | + |
| 77 | +顺带说一下Object的hashcode方法 |
| 78 | + |
| 79 | +```java |
| 80 | +// Returns a hash code value for the object. |
| 81 | +// 说白了,返回的就是该对象的地址值 |
| 82 | +public native int hashCode(); |
| 83 | +``` |
| 84 | + |
| 85 | +Equals的作用也是判断两个对象是否相等。但它一般有两种使用情况: |
| 86 | + |
| 87 | +- 情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过`==`比较这两个对象。 |
| 88 | + |
| 89 | +- 情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来比较两个对象的内容是否相等;若它们的内容相等,则返回 true (即,认为这两个对象相等)。 |
| 90 | + |
| 91 | +```java |
| 92 | +Integer a = new Integer(5); |
| 93 | +Integer b = new Integer(5); |
| 94 | +System.out.println(a.equals(b)); |
| 95 | +``` |
| 96 | + |
| 97 | +可以看一下Integer的equals方法: |
| 98 | + |
| 99 | +```java |
| 100 | +// 重写了Object的equals的方法 |
| 101 | +public boolean equals(Object obj) { |
| 102 | + if (obj instanceof Integer) { |
| 103 | + // 比较value |
| 104 | + return value == ((Integer)obj).intValue(); |
| 105 | + } |
| 106 | + return false; |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +hashcode的例子: |
| 111 | + |
| 112 | +```java |
| 113 | +public static void main(String[] args) { |
| 114 | + Set<Integer> set = new HashSet<>(); |
| 115 | + set.add(1); |
| 116 | + set.add(1); |
| 117 | + System.out.println(set.toString()); |
| 118 | +} |
| 119 | +``` |
| 120 | + |
| 121 | +在添加1的时候,先判断hashcode是否相同,如果相同,继续判断equals比较值,这样的好处是,如果hashcode相同就直接返回false了,减少了一次equals的判断,因为通常hashcode的值判断是否相等比较快,而equals相对于hashcode来讲慢一些。所以,如果不重写hashcode,我们看到object的hashcode是对象的内存值,那么set添加1判断的时候,hashcode永远不相等,那么就永远返回false,不管添加1,还是2,都是false。 |
0 commit comments