java基础知识(一)

导航

面向对象的特点

  • 封装:将事物封装成一个类,开放接口供外界调用,从而减少耦合与隐藏内部实现。当内部实现改变时,不影响外部调用。
  • 继承:从一个已知类中派生出一个新的类,新类拥有已知类的行为和属性。
  • 多态:本质是存在同名的不同方法,实现方式:
    • 子类对父类的方法重写
    • 方法重载
      • 方法的参数个数、顺序、类型不同
      • 修饰符、返回值、异常不同不构成重载

类的初始化顺序

  • 父类中的静态成员变量和静态代码块
  • 子类中的静态成员变量和静态代码块
  • 父类中的普通成员变量和代码块,执行父类的构造方法
    • 所以父类的构造方法被 private 修饰的话,则无法被继承
  • 子类中的普通成员变量和代码块,执行子类的构造方法

8 种基本数据类型

byte(1 字节),short(2 字节),int(4 字节),long(8 字节),float(4 字节),double(8 字节),char(2 字节),boolean

注解

  • 元注解
    • Target,注解的作用范围
    • Retention,注解的保留时间
    • Document,注解可被 javadoc 文档化
    • Inherited,注解可继承,也就是注解也应用于该 class 的子类
  • 定义注解
1
2
3
4
5
6
7
8
9
10
11
12
13
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface A {
int value() default -1;
}

@A(value = 1)
public class T {
public static void main(String[] args) {
A a = T.class.getAnnotation(A.class);
System.out.println(a.value());
}
}

反射

  • 运行时动态获取信息和动态调用方法的功能被称为反射
  • 相关的类
    • Class
      • 类.class
      • 对象.getClass()
      • Class.forName()
    • Method
    • Field
    • Constructor
  • 动态代理
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
public interface User {
void say();
}
public class UserImpl implements User{
@Override
public void say() {
System.out.println("hello");
}
}
public class ProxyHandler implements InvocationHandler {
private final Object target;

public ProxyHandler(Object target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("enter ...");
Object invoke = method.invoke(target, args);
System.out.println("exit ...");
return invoke;
}
}


public class T {
public static void main(String[] args) {
UserImpl userImpl = new UserImpl();
ProxyHandler proxyHandler = new ProxyHandler(userImpl);
User user = (User) Proxy.newProxyInstance(userImpl.getClass().getClassLoader(), userImpl.getClass().getInterfaces(), proxyHandler);
user.say();
// enter ...
// hello
// exit ...
}
}

泛型

  • 是在编译器这个层次来实现的,在生成的 java 字节码中是不包含泛型中的类型信息的。

序列化与反序列化

  • 实现 serializable 接口
  • ObjectOutputStream、ObjectInputStream
  • writeObject()、readObject()
  • transient

引用类型

  • 强引用:所指对象任何时候都不会被回收
  • 软引用:堆使用率接近临界值时回收
  • 弱引用:gc 时回收,可以通过弱引用的 get 方法得到引用对象
  • 虚引用:gc 时回收,gc 掉时会收到一个通知,不能通过 get 方法得到引用对象

JIT 编译器

just in time compile,也就是即时编译器,把经常运行的代码作为“热点代码”编译成与本地平台相关的机器码,并并行各种优化,包括逃逸分析、锁消除、锁膨胀、方法内联、空值检查消除、类型检测消除以及公共子表达式消除等。

逃逸分析的基本行为就是分析对象动态作用域,当一个对象在方法中被定义后,它可能被外部方法所引用,例如作为调用参数传递到其他地方中,称为方法逃逸。JIT 编译器的优化包括如下:
(1) 同布省略:也就是锁消除,当 JIT 编译器判断不会产生并发问题,那么会将同步 synchronized 去掉
(2) 标量替换
我们先来解释下标量和聚合量的基本概念。
(1) 标量(Scalar)是指一个无法再分解成更小的数据的数据。Java 中的原始数据类型就是标量。
(2) 聚合量(Aggregate)是还可以分解的数据。Java 中的对象就是聚合量,因为他可以分解成其他聚合量和标量。
在 JIT 阶段,如果经过逃逸分析,发现一个对象不会被外界访问的话,那么经过 JIT 优化,就会把这个对象拆解成若干个其中包含的若干个成员变量来代替。这个过程就是标量替换。标量替换的好处就是对象可以不在堆内存进行分配,为栈上分配提供了良好的基础。