Java 基础知识

1. 抽象类与接口的区别

(1). 抽象类

  • 抽象方法必须为 public(缺省默认) 或 protected,不能是 private

(2). 接口

  • 接口的变量会被隐式指定为 pulic static final (且只能是这种情况)

  • 接口的方法会被隐式指定为 public abstract (且只能是这种情况)

(3). 对比

  • 继承是一个 是不是 的关系,接口则是一个 有没有 的关系

  • 抽象类可以有静态代码块和静态方法,接口没有

  • 抽象类的成员变量可以是各种类型,接口只能是 public static final

  • 一个类只能继承一个抽象类,但可以实现多个接口

interface Alram {
    void alarm();
}
 
abstract class Door {
    void open();
    void close();
}
 
class AlarmDoor extends Door implements Alarm {
    void oepn() {
      //....
    }
    void close() {
      //....
    }
    void alarm() {
      //....
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

2. 反射

(1). 取得类类型 (Class Type)

Class a1 = Audi.class;
Class a2 = new Audi().getClass();

Class a3 = null;
try {
    a3 = Class.forName("com.imooc.reflection.Audi");
} catch (ClassNotoundException e){
    e.printStackTrace();
}

// 一个 Class 类只有一个类类型 (Class Type)
System.out.println(a1 == a2);  // true
System.out.println(a2 == a3);  // true
1
2
3
4
5
6
7
8
9
10
11
12
13

(2). 通过类类型(Class Type) 创建实例

Car car;
try {
    car = (Car) a1.newInstance();
    a1.start();
} catch (Exception e){
    e.printStackTrace();
}
1
2
3
4
5
6
7

TIP

  • 运行时加载类,为 动态加载
  • 编译时加载类,为 静态加载
  • 上面的代码,编译时无需加载相关类,为 动态加载

(3). 取得类的方法、属性等

a1.getName();       // com.imooc.reflection.Auti
a1.getSimpleName(); //Audi

Method[] methods1 = a1.getMethods();
Method[] methods2 = a1.getDeclaredMethods();

Method[] fields1 = a1.getFields();
Method[] fields2 = a1.getDeclaredFields();

Class[] types = method[1].getParameterTypes(); //int, java.lang.String, etc...
method[1].getReturnType().getSimpleName();     //int, String, etc...

1
2
3
4
5
6
7
8
9
10
11
12

TIP

  • getMethods()

    • 返回所有公共(public)的方法

    • 包括 父类的方法

  • getDeclaredMethods()

    • 返回所有自己声明的方法(不包括父类的方法)

    • 包括 自己声明的私有(private)方法

  • getFields(), getDeclaredFields() 类同。

(4). 反射操作

// Audi.refuel(Long size)

Audi audi = (Auti)a1.newInstance();
Method refuel = a1.getMethod("refuel", Long.class);  
refuel.invoke(audi, 50);
1
2
3
4
5

3. Iterable, Collection, Map 及其子集

(1). 类图

(2) HashMap, HashTable, ConcurrentHashMap

  • HashMap 是线程不安全的,在并发环境下,可能会形成环状链表(扩容时可能造成),导致 get 操作时,cpu 空转,所以,在并发环境中使用 HashMap 是非常危险的。

  • HashTable 和 HashMap 的实现原理几乎一样,差别无非是 1.HashTable 不允许 key 和 value 为 null; 2. HashTable 是线程安全的。但是 HashTable 线程安全的策略实现代价却太大了,简单粗暴,get/put 所有相关操作都是 synchronized 的,这相当于给整个哈希表加了一把大锁,多线程访问时候,只要有一个线程访问或操作该对象,那其他线程只能阻塞,相当于将所有的操作串行化,在竞争激烈的并发场景中性能就会非常差。

最近更新: 8/11/2019, 3:37:25 PM