Java基础01

1. 值传递 VS 引用传递

1
2
int a = 1101; 
String b = "hello";

image-01.png

基本数据类型的变量里直接存放引用类型的变量存放的是实际对象的地址

1
2
3
4
5
6
7
8
9
10
11
void fun(int a){
a = 0;
}
fun(a);
//实际上是实参a的值传递给形参a,不会改变原a的值

void fun(String b){
b = "world";
}
fun(b);
//实际上是实参b的地址传递给形参b,形参b改变其指向的地址,实参b的指向不会发生变化

JAVA只有值传递,没有引用传递。

2. == VS equals

  • 对于基本数据类型,==比较的是两个变量的值是否相等。
1
2
3
int a = 10;
int b = 10;
System.out.println(a == b); //true
  • 对于引用类型,==比较的是两个变量是否指向同一地址。
1
2
3
String a = "hello";
String b = new String("hello");
System.out.println(a==b); //false

JAVA中所有对象都继承自object类,equals是object类的方法之一。

1
2
3
public boolean equals(Object obj) {
return (this == obj);
}

但是对于我们常用的String类来说,它重写了equals方法。

1
2
3
String a = "hello";
String b = new String("hello");
System.out.println( a.equals(b) ); //true

String类的equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

并不是说 == 比较的就是引用是否相等,equals 比较的就是值,具体情况具体分析。

3. 为什么重写equals()时必须重写hashCode()方法?

  • 如果两个对象的hashCode 值相等,那这两个对象不一定相等(哈希碰撞)。
  • 如果两个对象的hashCode 值相等并且equals()方法也返回 true,我们才认为这两个对象相等。
  • 如果两个对象的hashCode 值不相等,我们就可以直接认为这两个对象不相等。

如果重写 equals() 时没有重写 hashCode() 方法的话就可能会导致 equals 方法判断是相等的两个对象,hashCode 值却不相等。

4. String/StringBuffer/StringBuilder

  • 操作少量的数据: 适用 String (不可变)

  • 单线程操作字符串缓冲区下操作大量数据: 适用 StringBuilder

  • 多线程操作字符串缓冲区下操作大量数据: 适用 StringBuffer

5. String s1 = new String(“abc”) 创建了几个字符串对象?

  • 如果字符串常量池中不存在字符串对象“abc”的引用,那么会在堆中创建 2 个字符串对象“abc“

  • 如果字符串常量池中已存在字符串对象“abc”的引用,则只会在堆中创建 1 个字符串对象“abc”