一些摘记和总结

Top

  1. separate Interface from Implementation – decouple What from How
  2. primitive的Wrapper类没有无参的默认构造函数,所以不可使用class.newInstance()方法

JDK中的Final Imutable类

这里的final是java的关键字,而Imutable不是;

  1. final修饰类的时候,表示该类不能被继承
  2. final修饰对象引用的时候,表示该引用不能改变,即不能指向其他对象,但还是可以改变当前对象的状态
  3. final修饰primitive的时候,表示‘常量’

Imutable,即不可改变,是一种状态,当说一个对象是Immutable的时候,说明不能改变这个对象的状态

JDK中的String,还有primitive的包装类Wrapper(Integer, Long, Character…)都是final+Imutable

String类和Wrapper类都是Imutable的,但二者的实现机制却不同

1. 对于`String`类,其实现`Imutable`是通过将成员变量修饰成`private`的(`private final char value[];`),之后不提供`set`方法==!
2. 对于`Wrapper`类,如`Integer`,其直接将成员变量修饰成`final`的(`private final int value;`)

至于为什么要将这些Imutable的类修饰成Final的,是因为Final使得类不能被继承,这样也就避免了子类中添加修改类对象内容的方法,所以Immutable类都要加上Final

Immutable好处主要是线程安全,不用担心其他线程修改了当前对象

TODO 如何设计Immutable

  1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
  2. All fields of Immutable class should be final.
  3. Object must be properly constructed i.e. object reference must not leak during construction process.
  4. Object should be final in order to restrict sub-class for altering immutability of parent class.

Read more

访问权限

两类权限:

  1. Class: public, 空(包权限)
  2. Class members: public, protected, 空(package access), private

子类可以放大继承方法的权限,反之不可,因为子类缩小继承方法权限没什么意思,因为可以通过upcast到父类获取这些权限

类加载顺序

三个原则:

  1. 先加载父类之后加载生成类
  2. 先加载类变量(和static块,按照顺序)之后加载构造函数
  3. 递归调用1,2

由此可见,构造函数其实是Static

泛型Generic

  1. Add type parameter to class
  2. ensure compile-time safety
  3. Anything that needs the knowledge of the exact type at run-time will not work

java中泛型基于Erasure擦除机制,运行时,所有的泛型都被Erasure成原始类型,所以,所有涉及到运行是类型的方法都无效

异常Exception

一般异常的处理有两种机制:

  1. 终止Termination,认为抛出的异常无法恢复,这也是Java使用的异常处理机制
  2. 恢复Resumption,认为异常有补救措施,不throw,而调用补救函数

java中的异常包结构 TODO

受检异常:checked and enforced at compile time

如果不想让在catch自定义的异常,可以使其继承RuntimeException

Finnaly

try { ... }
catch(...) {...}
finnaly {...}

finnaly的作用,Java中有GC垃圾自动回收机制,所以不需要在finally中释放内存,但程序员仍然需要释放其他资源,如文件流,网络链接等

注意,finnaly中的returnthrow会覆盖try语句中的…

类型检查

主要分两类:

  1. 静态类型检查(static type checking),即在编译时进行,需要变量声明后再使用,如:C(++),Java等
  2. 动态类型检查(dynamic type checking),即在运行时进行,变量直接使用,不用提前声明,如python,php

和其类似的一组概念是:

  1. 弱类型(Weak Type): 变量类型不确定,如php,c(++)(c中可以将一块内存做多种类型处理)
  2. 强类型(Strong Type): 变量的类型固定,不能随意转换,如python,Java

C(++)是介于强弱类型之间的语言,由于C(++)支持多种隐含类型转换,有人认为是弱类型语言;也有人认为,C(++)对不同数据类型的操作已有足够多的限制,算是强类型的

两组概念是独立的,如下表所示:

正交关系 动态类型检查 静态类型检查
弱类型 C(++) php
强类型 Java Python

Class对象

每个类都有一个Class对象保存其类型信息,类加载器使用其创建对象,RTTI也是通过其获取对象类型信息

JVM第一次加载一个类时(使用类的静态成员,包括静态变量,构造方法),生成该类的Class对象

类加载器首先检查内存中(TODO 方法区?)是否含有某个类的Class对象,如果没有,则从该类的.class文件中读取并生成

程序可以通过下面几种方法获取类的Class对象:

  1. Class.forName("MyClass")
  2. myObj.getClass()
  3. MyClass.class (recommended)

System.out.format("%s = %s : %s\n", Boolean.class, boolean.class, Boolean.class == boolean.class); System.out.format("%s = %s : %s\n", Boolean.TYPE, boolean.class, Boolean.TYPE == boolean.class);

反射 reflect

TODO 动态代理

IO 输入输出

  1. 标准输入输出 Standard I/O
    Unix的设计理念,程序有单一的输入输出流
    Java中,有System.in, System.out, System.err
  2. New IO 为了提高速度,增加了两个东西:TODO通道channels和缓冲buffers

并发多线程 multithreading

并发多线程有两种策略:

  1. preemptive抢占式多任务处理,java采用基于时间片的抢占机制,因此并发的线程数有上限,否则会产生饥饿
  2. cooperative 协作式多任务处理

TODO implement more

序列化 Serializable

TODO java.lang.Serializable是一个空接

TOP