如果没有任何构造函数,编译器会偷偷帮你生成一个无参数的构造器
重载时,如果一个方法调用可以匹配多个方法声明时,类型最匹配的最优先调用
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
public class Main {
// 默认会调用这个方法,因为1这个常量是int类型
public static void foo(int i) {
System.out.println(i);
}
// 如果注释以上所有的方法,则会调用这个方法,因为int能被自动装箱成Integer
public static void foo(Integer i) {
System.out.println(i);
}
// 如果注释以上所有的方法,则会调用这个方法,因为Integer继承了Number
public static void foo(Number i) {
System.out.println(i);
}
// 如果注释以上所有的方法,则会调用这个方法,因为Number继承了Object
public static void foo(Object i) {
System.out.println(i);
}
public static void foo(List list) {
System.out.println(i);
}
public static void main(String[] args) {
// 请问以下代码,会调用哪个签名的方法?
foo(1);
foo(null); // 这行代码会报错? 为什么? 怎么解决?
/*
因为null没有类型,下面的方法和List签名的方法冲突,编译器不知道该调用哪个
因此你需要告诉编译器到底该调用哪个方法,可以用强制转换来解决
foo((List)null)
*/
/*
如果把List签名的方法注释掉,程序又不报错了,为什么?
答:因为根据类型匹配规则,null没有类型,因此int签名的方法被排除,接下来
考虑对象类型,又因为Integer是Number的子类Number又是Object的子类,
因此Integer最先匹配,所以它会调用Integer签名的方法
那么为什么加上List签名的方法会编译器会找不到而报错呢?
答:因为List和Integer都是Object的子类,List和Integer之间不构成父子类型
它们到Object类之间的距离相同,因此编译器不知道该调用哪个方法
*/
}
}
|
1. 静态成员
2. 静态代码块
3. 实例成员
4. 实例代码块
5. 构造器
6. 在继承体系中,继承链最顶端的先初始化,然后依次向下
1. public 所有人都可以访问
2. protected 子类和同包中的类可以访问
3. package private 包级私有(默认什么修饰符都不写就是包级私有),同包的可以访问
4. private 私有,只有自己可以访问
5. 包级私有是可以被绕过的
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
public class Person {
private String name;
private int age;
private static final Person INVALID_PERSON = new Person("INVALID Person", 0);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/**
* 私有化构造器
* @param name 名字
*/
private Person(String name) {
this(name, 20);
}
/**
* 私有化构造器
* @param name 名字
* @param age 年龄
*/
private Person(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 静态工厂方法的好处
* 1. 名字可以和类名不同,可以通过名字很好的了解函数的意图
* 2. 静态工厂方法还可以返回一个预先定义好的实例,从而不用每次都new对象
* 3. 静态工厂方法还可以返回子类对象,而构造器只能返回本类对象
* @param age 年龄
* @return 返回对应年龄的张三
*/
public static Person newZhangSan(int age) {
if (age < 0 || age > 200) {
return INVALID_PERSON;
}
return new Person("张三", age);
}
}
|