java中经常忘记的几个知识点

忘记点1:匿名内部类的使用

使用情境

通常在实现接口继承抽象父类的时候需要使用到匿名内部类

实现接口:

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
public interface Product{
double getPrice();
double getName();
}

public class Anony{
public void test(Product product){
System.out.println("购买了一个"+product.getName()+",花掉了"+product.getPrice());
}
}

pubic class Test{
public static void main(String[] args){
Anony anony=new anony();
// 注意,此处要传入一个匿名类对象
anony.test(new Product(){
@Override
public double getPrice(){
return 578.6;
}
@Override
public String getName(){
return "联想笔记本";
}
}
);
}
}

调用了Anony的test方法,并为其传入一个新new的Product实例作为参数

打印结果:

image-20210819141211652

继承抽象父类

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
public abstract class Device{
private String name;
public abstract double getPrice();
public String getName(){
return name;
}
public Device(){}
public Device(String name){
this.name=name;
}
}

public class Device{
public void test(Device device){
System.out.println("购买了一个"+device.getName()+"花费了"+device.getPrice());
}
}

pubic class Test{
public static void main(String[] args){
Anony anony=new anony();
// 注意,此处要传入一个匿名类对象
anony.test(new Device("海尔电视机"){
@Override
public double getPrice(){
return 578.6;
}
);
Device device=new Device(){
@Override
public double getPrice(){
return 556.56;
}
@Override
public String getName(){
return "美的电视机";
}
};
annoy.test(device);
}
}

调用、传参过程与上一个相似

打印结果:

image-20210819141434202

忘记点2:super关键字的使用

super指向当前对象的父类特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//父类,Animal类
class Animal {
//构造函数
public Animal() {
System.out.println("Animal类的无参数构造函数执行");
}
}

//子类,Cat类
class Cat extends Animal{
//构造函数
public Cat() {
System.out.println("Cat类的无参数构造函数执行");
}
}

执行下面代码

1
Cat c1 = new Cat(); 

打印结果:

image-20210819141724393

默认会在构造方法中的第一行隐式地添加一个父类的无参构造函数(也可以手动添加其他构造函数,如下图)

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
public class MyTest {

public static void main(String[] args) {
new Cat();
}
}

//父类,Animal类
class Animal {
//构造函数
public Animal() {
super();
System.out.println("1:Animal类的无参数构造函数执行");
}
public Animal(int i) {
super();
System.out.println("2:Animal类的有int参数构造函数执行");
}
}

//子类,Cat类
class Cat extends Animal{
//构造函数
public Cat() {
this("");
System.out.println("3:Cat类的无参数构造函数执行");
}
public Cat(String str) {
super(5);
System.out.println("4:Cat类的有String参数构造函数执行");
}
}

忘记点3:this关键的使用

this指向当前对象自己,super指向当前对象的父类型特征,故this的东西比super多,也就是super是this的一部分;

忘记点4:static的作用

从可见性来看:有static修饰的时候,对外是可见的;否则,对外不可见,必须有一个外部类(或者对象)的引用才可使用

从内存分析来看:static修饰的变量,存储在方法区静态域中,被所有线程共享(方法区包含所有的class和static变量)

案例:静态和非静态内部类

两种的创建对象方式不同

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
// 1.定义一个函数式接口
interface Like {
void lambda();
}
public class TestLambda {
// 3.非静态内部类(对外不直接可见,必须有一个外部类的引用才能被创建)
class Like2 implements Like {
@Override
public void lambda() {
System.out.println("我喜欢lambda2");
}
}
// 4.静态内部类(对外直接可见,可以直接创建对象)
static class Like3 implements Like {
@Override
public void lambda() {
System.out.println("我喜欢lambda3");
}
}
public static void main(String[] args) {
Like like;

like = new TestLambda().new Like2(); // 创建非静态内部类
like.lambda();

like = new Like3(); // 创建静态内部类
like.lambda();
}
}

忘记点5:try中有return,finally还会执行吗

答案是肯定的,java官方文档是这么描述的:

​ The finally block always executes when the try block exits.`

即try执行完成之后,finally一定会执行的。这个特性可以让程序员避免在try语句中使用了return,continue或者break关键字而忽略了关闭相关资源的操作。把清理相关资源放在finally语句块中一直是最佳实践。

更详解释:(10条消息) try中有return,finally还会执行吗?_Hningning的博客-CSDN博客

Contents
  1. 1. 忘记点1:匿名内部类的使用
    1. 1.1. 使用情境
      1. 1.1.1. 实现接口:
      2. 1.1.2. 继承抽象父类
  2. 2. 忘记点2:super关键字的使用
  3. 3. 忘记点3:this关键的使用
  4. 4. 忘记点4:static的作用
    1. 4.1. 案例:静态和非静态内部类
  5. 5. 忘记点5:try中有return,finally还会执行吗
|