Java基础 —— 面试题目

本文最后更新于:2022年7月1日 晚上

概览:Java基础

预警!仅用于本人快速自学,不过欢迎指正。

1. 引用类型的例题解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Main {
public static void main(String[] args) {
Person p = new Person();
String[] fullname = new String[] { "Homer", "Simpson" };
p.setName(fullname); // 传入fullname数组
System.out.println(p.getName()); // "Homer Simpson"
fullname[0] = "Bart"; // fullname数组的第一个元素修改为"Bart"
System.out.println(p.getName()); // "Homer Simpson"还是"Bart Simpson"?
}
}

class Person {
private String[] name;

public String getName() {
return this.name[0] + " " + this.name[1];
}

public void setName(String[] name) {
this.name = name;
}
}

最终结果是:

1
Bart Simpson

原因:数组存储了地址,0x11和0x12,然后将数组赋值给了p对象,p对象指向了0x11;之后0x11被替换成了0x13,所以最终结果也替换成了0x13。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Main {
public static void main(String[] args) {
Person p = new Person();
String bob = "Bob";
p.setName(bob); // 传入bob变量
System.out.println(p.getName()); // "Bob"
bob = "Alice"; // bob改名为Alice
System.out.println(p.getName()); // "Bob"还是"Alice"?
}
}

class Person {
private String name;

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}
}

最终结果:

1
Bob

原因:p的地址指向了bob指向的0x11,然后bob指向了0x12,但是没有改变p的指向。

2.static 的执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Magic {
private static Magic instance = new Magic();
private static int count = 1;
// private static final int count = 1;
private Magic() {
System.out.println(count);
}
public static Magic getInstance() {
return instance;
}


public static void main(String[] args) {
Magic.getInstance();
}
}

问最终打印输出的是多少?

1
2
3
4
5
6
- 在JDK8之下,打印输出的是0

- 在类加载阶段的第二部链接阶段,会为static变量分配内存,设置为默认值。
static变量分配空间和赋值是两个步骤,分配空间是在准备阶段完成的,赋值是在初始化阶段完成的。
而如果static变量是final修饰的,并且是基本类型或者String类型,那么在编辑阶段值就会确定,这时候准备阶段就会赋值。
如果是final修饰的其他引用类型,那么也是在初始化阶段完成的。

如果加上final修饰符号呢?打印输出的是多少

1
2
- 在JDK8之下,打印输出的是1
同上面的解释,赋值是在准备阶段完成的,这时就是1

3.重写一个equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public boolean equals(Object o) {
// 1.比较本身,如果是自己的话返回true
if (this == o) return true;
// 2.如果o为null或者两者类型不匹配
if (o == null || getClass() != o.getClass()) return false;
// 3.强转类型
Student student = (Student) o;
// 4.基本类型比较用==,引用类型用equals方法
return age == student.age && Objects.equals(name, student.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

Objects.equals的实现

1
2
3
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!