#《head first java》要点
##基本概念
- 语句以分号结束
- 程序块以{}划出范围
- 用名称与类型声明变量
##类与对象
- 所有的java程序都定义在类中
- 类是对象的蓝图
- 对象本身已知的事物称为实例变量,代表对象的状态
- 对象可执行的动作称为方法,代表对象的行为
- java程序在执行期是一组会交互的对象
##primitive主数据类型和引用
- 变量有两种:primitive主数据类型和引用
- 变量的声明必须有类型和名称
- primitive主数据类型变量值是该值的字节所表示的
- 引用变量的值代表位于堆之对象的存取方法
- 没有引用到任何对象的引用变量的值为null值
- 数组一定是个对象,不管所声明的元素是否为primitive主数据类型,并且没有primitive主数据类型的数组,只有装载primitive主数据类型的数组
##方法操作实例变量
- 类定义对象的所知和所为
- 对象所知为实例变量
- 对象所为是方法
- 传给方法的参数必须符合声明时的数量、顺序和类型
- 方法必须声明返回类型,使用void类型代表方法不返回任何东西
- 如果方法声明了非void的返回类型,就一定要返回与声明类型相同的值
- java通过值传递参数,不管是什么数据类型,都是以拷贝传递,引用变量也是传递引用(值)的拷贝
- 实例变量永远都会有默认值,如果没有明确的赋值给实例变量,或者调用setter,实例变量会有默认值 0/0.0/false/null
- 局部变量没有默认值,如果在变量被初始化前使用,编译器会报错
##继承与多态
- 子类是extends父类出来的
- 继承下来的方法可以被覆盖,但实例变量不能被覆盖
- 使用IS-A测试来验证继承结构的合理性
- IS-A关系是单方向的
- 如果类Y继承类X,且类Y是类Z的父类,那么Z应该能通过IS-A X的测试
- 当某个方法在子类中被覆盖过,调用这个方法时会调用覆盖过的版本
- 覆盖父类的方法,参数必须一样,且返回类型必须兼容,不能降低方法的存取权限
- 重载方法是两个方法的名称相同,但参数不同,它与继承或多态无关
##接口与抽象类
- 如果不想让某个类被初始化,就以abstract标记为抽象的
- 抽象的类可以带有抽象和非抽象的方法
- 如果声明出一个抽象的方法,必须将类也标记为抽象的,不能在非抽象类中拥有抽象方法
- 抽象的方法没有内容,它的声明以分号结束
- 必须实现所有的抽象方法
- java所有的类都是Object直接或间接的子类
- Object引用变量在没有类型转换的情况下不能赋值给其他的类型
- 不管实际上所引用的对象是什么类型,只有在引用变量的类型就是带有某方法的类型时才能调用该方法
- java不允许多重继承,因为那样会有致命方块的问题
- 接口就像是100%纯天然抽象类
- class可以实现多个接口
- 实现某个接口的类必须实现它的所有方法
- 要从子类调用父类的方法可以用super来引用
##构造器与垃圾收集器
- 所有局部变量都存在于栈上对应的堆栈块中
- 对象引用变量与主数据类型变量都放在栈上
- 不管是实例变量或局部变量,对象本身都会在堆上
- 实例变量保存在所属的对象中,位于堆上。
- 如果实例变量是个对对象的引用,则引用与对象都是在堆上。
- 构造函数是个会在新建对象的时候执行的程序代码
- 构造函数必须与类同名且没有返回类型。
- 如果没有写构造函数,编译器会帮你安排一个。
- 默认的构造函数是没有参数的。
- 构造函数可以是public或private或不指定,私有的构造函数可以用于单例模式
- 重载的构造函数必须有不同的参数(参数类型和顺序)。
- 实例变量有默认值,原始的默认值是 0/0.0/false,引用的默认值是 null。
- 在创建新对象时,所有继承下来的构造函数都会执行,而且父类的构造函数先执行
- 构造函数可以有参数,并且可以被重载
- 通过调用super()来调用父类的构造函数,如果没有显式调用super(),编译器会帮我们加上super()的调用,但只会是无参数的版本
- 使用this()来从某个构造函数调用同一个类的另外一个构造函数。this()只能用在构造函数中,且必须是第一行语句。super()与this()不能兼得。
- 对象生命周期
- 局部变量只会存活在声明该变量的方法中
- 实例变量的寿命与对象相同
- 3种方法可以释放对象的引用
- 引用永久的离开它的范围,比如方法执行结束
- 引用被赋值到其他的对象上
- 直接将引用设为null
##静态
- 静态方法应该用类名来调用,而不是对象引用变量。
- 静态方法不能存取非静态的变量或方法。
- 如果类只有静态方法,可以将构造函数标记为private避免被初始化。
- 静态变量为所属类的成员共享,只有一份,而不是每个实例都有自己的一份。
- 静态方法可以存取静态变量。
- 静态变量会在该类的任何静态方法执行之前初始化。
- java的常量是把变量同时标记成static和final。
- final的静态变量必须在声明或静态初始化程序中赋值。
- 常量的命名惯例是全部大写。
- final值不能修改,final方法不能被覆盖,final类不能被继承。
##异常
- 方法可以在运行期间遇到问题抛出异常
- 异常是Exception类型的对象
- 编译器不会注意RuntimeException类型的异常
- 方法可以用throw关键词抛出异常对象
- 可能会抛出异常的方法必须声明成throws Exception
- 如果要处理异常,把调用包在try/cache块中,并将异常处理程序放在cache块中
- 如果不想处理异常,通过声明throws Exception抛出
##线程
- 如果两个或以上的线程存取堆上相同的对象可能出现严重的问题
- 要让对象在线程上有足够的安全性,就要判断出哪些指令不能被分割执行
- 使用synchronized关键词修饰符可以防止两个线程同时进入同一个对象的同一个方法
- 每个对象都有单一的锁,单一的钥匙,这只会在对象带有同步化方法时才有实际的用途
- 线程尝试要进入同步化过的方法时必须要取得对象的钥匙,如果因为已经被别的线程拿走了,就得等
- 对象就算有多个同步化过的方法,也还是只有一个锁,一旦某个线程进入该对象的同步化方法,其他线程就无法进入该对象的任何同步化方法
- 同步化可能会导致死锁
- 每个被载入的类也有个锁,当对静态方法做同步化时,用的是类本身的锁
##集合与泛型
- 运用泛型可以创建类型安全更好的集合,让问题尽可能在编译期间就能抓到,而不会等到执行期才冒出来
- 引用相等性:引用到堆上的同一个对象的两个引用是相等的。hashcode一定相等,使用==或equals()来比较
- 对象相等性:堆上的不同对象在意义上相同。覆盖从Object继承下来的hashCode()方法与equals()方法