文章目录

  • Java核心技术卷一读书笔记
  • 第一章 Java程序设计概述
  • 1.1 关键特性
  • 第二章 Java程序设计环境
  • 2.1 使用命令行工具
  • 第三章 Java的基本查询设计结构
  • 3.1 数据类型
  • 3.2 运算符
  • 3.3 数值之间的合法转换
  • 3.4 输入输出
  • 3.5 控制流程
  • 第四章 对象与类
  • 4.1 用户自定义类
  • 4.2 方法参数
  • 4.3 对象构造
  • 4.4 类设计技巧
  • 第五章 继承
  • 5.1 类、超类和子类
  • 5.2 Object:所有类的超类
  • 5.3 泛型数组列表
  • 5.4 对象包装器与自动装箱
  • 5.5 参数数量可变的方法
  • 5.6 反射
  • 5.7 继承的设计技巧
  • 第六章 接口、Lambda表达式与内部类
  • 6.1 接口
  • 6.2 Lambda表达式
  • 6.3 内部类
  • 6.4 代理
  • 第七章 异常、断言和日志
  • 7.1 处理错误
  • 7.2 捕获异常
  • 7.3 使用异常机制的技巧
  • 7.4 记录日志
  • 第八章 泛型程序设计
  • 8.1 好处
  • 8.2 定义简单泛型类
  • 8.3 泛型方法
  • 8.4 类型变量的限定
  • 8.5 泛型代码和虚拟机
  • 8.6 约束与局限性
  • 8.7 通配符类型
  • 8.8 反射和泛型
  • 第九章 集合
  • 9.1 Java集合框架
  • 9.2 具体集合
  • 9.3 映射
  • 第十章 并发
  • 10.1 线程
  • 10.2 线程中断
  • 10.3 线程状态
  • 10.4 线程属性
  • 10.5 同步


Java核心技术卷一读书笔记

第一章 Java程序设计概述

1.1 关键特性

  • 简单
  • 面向对象
  • 分布式
  • 健壮性
  • 安全性
  • 体系结构中立
  • 可移植性
  • 解释性
  • 高性能性
  • 多线程
  • 动态性

第二章 Java程序设计环境

2.1 使用命令行工具

  • 注意:
  • 注意大小写
  • 编译器需要一个文件名,而运行程序时,只需要指定类名,不需要扩展名

第三章 Java的基本查询设计结构

3.1 数据类型

  • 八种基本类型:四种整型、两种浮点类型、char和boolean。
  • 整型:
  • int
  • short
  • long
  • byte
  • 浮点类型
  • float 后缀f
  • double 后缀d或者没有
  • 布尔值boolean:整型和布尔值之间不能进行转化

3.2 运算符

  • 使用strictfp可以保证严格的浮点计算。

3.3 数值之间的合法转换


java核心技术卷一卷二有必要看吗 java核心技术 卷一_构造器

3.4 输入输出

  • 读取输入
  • 需要构造一个Scanner对象,并与标准输入流System.in关联。
  • 密码的输入
  • 使用Console类

一个JVM是否有可用的Console,依赖于底层平台和JVM如何被调用。如果JVM是在交互式命令行(比如Windows的cmd)中启动的,并且输入输出没有重定向到另外的地方,那么就可以得到一个可用的Console实例。
  但当使用Eclipse等IDE运行以上代码时Console中将会为null。
  表示Java程序无法获得Console实例,是因为JVM不是在命令行中被调用的,或者输入输出被重定向了。

  • 格式化输出
  • 可以使用s转换符格式化任意的对象。对于任意实现了Formattable接口的对象都将调用formatTo方法。否则将调用toString方法。

3.5 控制流程

  • switch
  • case标签:
  • 类型为char、byte、short、或int的常量表达式
  • 枚举常量
  • 字符串字面量

第四章 对象与类

4.1 用户自定义类

  • 构造器
  • 构造器与类同名
  • 每个类有一个以上的构造器
  • 构造器可以有多个或者没有参数
  • 构造器没有返回值
  • 构造器总是伴随着new操作一起调用的
  • 隐式参数与显式参数
  • 隐式:是出现在方法名前面的类对象
  • 显式:位于方法名后括号中

在每一个方法中关键字this表示隐式参数

4.2 方法参数

  • 参数传递
  • 按值调用:表示方法接收的是调用者提供的值(java)
  • 按引用调用:表示方法接收的是调用者提供的变量地址
  • java对对象采用的不是引用代用,是按值传递
  • 一个方法不能修改一个基本数据类型的参数(数值型或布尔型)
  • 一个方法可以改变一个对象参数的状态
  • 一个方法不能让对象参数应用一个新的对象

4.3 对象构造

  • 调用另一个构造器
  • 使用this

4.4 类设计技巧

  • 一定要保证数据私有
  • 一定要对数据初始化
  • 不要再类中使用过多的基本类型
  • 不是所有的域都需要独立的与访问器和域更改器

第五章 继承

5.1 类、超类和子类

  • 关键词super使用父类的方法。
  • 如果子类的构造器没有显式地调用超类的构造器,则将自动地调用超类默认的构造器。

this:

引用隐式参数

调用该类其他的构造器

super

调用超类的方法

调用超类的构造器

5.2 Object:所有类的超类

  • Object.equals(a,b):判断相等。
  • equals:
  • 特性:
  • 自反性
  • 对称性
  • 传递性
  • 一致性
  • 对于任意非空引用x,x.equals(null)应该返回false。
  • 编写建议:
  • 显示参数命名为otherObject,稍后需要将它转换成另一个叫做other的变量
  • 检测this与otherObject是否引用同一个对象
  • 检测otherobject是否为null,如果是null,返回false
  • 比较this与otherObject是否属于同一个类
  • 如果equals的语义在每个子类中有所改变就使用getClass检测
  • 没有就使用instanceof检测
  • 将otherObject转化为相应的类类型变量
  • 比较需要比较的域
  • 使用==比较基本类型域
  • 使用equals比较对象域
  • hashCode方法
  • equals与hashCode的定义必须一样,比较的属性和散列的属性必须是一致的。
  • toString方法
  • 在调用String()的地方都可以使用"+x"来代替。
  • 但是数组继承的是object的toString方法,数组类型将按照旧的格式打印,修正的方式是调用静态方法Arrays.toString
  • valueOf方法:toString的逆方法。

5.3 泛型数组列表

  • ArrayList是一个采用类型参数的泛型类。

5.4 对象包装器与自动装箱

  • 对象包装器类是不可变的,还是final,因此不能定义它们的子类
  • 自动装箱规范要求boolean、byte、char<=127,介于-128~127之间的short和int被包装到固定的对象中。

5.5 参数数量可变的方法

  • 使用关键字…,表示可以接受任意数量的对象

5.6 反射

  • 能够分析类能力的程序称为反射
  • 机制:
  • 在运行时分析类的能力
  • 在运行时查看对象,例如编写一个toString方法供所有类使用
  • 实现通用的数组操作代码
  • 利用Method对象

5.7 继承的设计技巧

  • 将公共操作和域放在超类
  • 不要使用受保护的域
  • 使用继承实现“is-a”关系
  • 除非所有继承的方法都有意义,要不不要使用继承
  • 在覆盖方法时,不要改变预期的行为
  • 使用多态,而非类型信息
  • 不要过多的使用反射

第六章 接口、Lambda表达式与内部类

6.1 接口

  • 类实现一个接口
  • 将类声明为实现给定的接口
  • 对接口中的所有方法进行定义
  • 接口声明的时候默认所有的方法都是public,可以不声明,但是在实现类的时候必须将方法声明为public。
  • 接口的特性
  • 接口不是类,不能通过new来实例化
  • 可以声明接口的变量
  • 接口变量必须引用实现了接口的类对象
  • 接口中不能包含实例域或静态方法,但可以包含常量。
  • 接口中的方法被自动设置为public,接口中的域被自动设为public static fianl。
  • 1.8以后可以在接口类中增加静态方法
  • 解决默认方法冲突
  • 超类优先:如果一个超类提供了一个具体方法,同名且有相同参数类型的默认方法会被忽略
  • 接口冲突:如果一个超接口提供了一个默认方法,另一个接口提供了一个同名且参数类型不同的方法,必须覆盖这个方法来解决冲突
  • 类优先原则:一个类扩展了一个超类且同时实现了一个接口,并且从超类和接口继承了相同的方法,这种情况下只会考虑超类方法,接口的所有默认方法都会被忽略

6.2 Lambda表达式

  • 例子:
import javax.swing.*;
import javax.swing.Timer;
import java.util.*;


public class promble{
    public static void main(String[] args) {

       String[] planets= new String[]{"sdad","sdadasd","dasda","adasdaw","dawqfaf"};
        System.out.println(Arrays.toString(planets));
        System.out.println("Sorted in dictionary order:");
        Arrays.sort(planets);
        System.out.println(Arrays.toString(planets));
        System.out.println("Sort by length:");
        Arrays.sort(planets,(first,second)->first.length()-second.length());
        System.out.println(Arrays.toString(planets));

        Timer t =new Timer(1000, event->
                System.out.println("The time is" + new Date()));
        t.start();
        JOptionPane.showMessageDialog(null,"dadasd?");
        System.exit(0);
    }
}
  • 函数式接口
  • 对于只有一个抽象方法的接口,需要这种接口的对象是,就可以提供一个lambda表达式,这种接口就是函数式接口

6.3 内部类

  • 用途:
  • 内部类可以访问该类定义所在的作用域中的数据,包括私有的数据
  • 内部类可以对同一个包中的其他类隐藏起来
  • 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷
  • 内部类中声明的所有静态域都必须是fianl。

6.4 代理

  • 代理类可以在运行时常见全新的类,这样的代理类能够实现指定的接口。尤其是具有下列方法:
  • 指定接口所需的全部方法
  • Object类中的全部方法,例如:toString、equals等
  • 创建代理对象,需要使用Proxy类的newProxyInstance方法,其参数:
  • 一个类加载器
  • 一个Class对象数组,每个元素都是需要实现的接口
  • 一个调用处理器
  • 代理类的特性
  • 是在程序运行时创建的,一旦被创建就变成了常规类
  • 所有代理类都扩展于Proxy类,一个代理类只有一个实例域。

第七章 异常、断言和日志

7.1 处理错误

  • 异常分类
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qmV89GjJ-1582015998643)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200211142437.png)]
  • Error:Java运行时系统内部错误和资源耗尽错误。
  • Exception
  • RuntimeException
  • 错误的类型转化
  • 数组访问越界
  • 访问null指针
  • 其他
  • 试图在文件尾部后面读取数据
  • 试图打卡一个不存在的文件
  • 试图根据给定的字符串查找Class对象,而这个字符串表示的类并不存在
  • 声明受查异常:
  • 以下情况需抛出异常
  • 调用一个抛出受查异常的方法
  • 程序运行过程中发现错误,并且利用throw语句抛出一个受查异常
  • 程序出现错误
  • java虚拟机和运行时库出现的内部错误
  • 创建异常类
  • 定义一个派生于Exception的类,或者派生于Exception子类的类。应该包含两个构造器,一个是默认构造器一个是带有详细描述信息的构造器
class FileFormatException extends IOException{
    public FileFormatException(){}
    public FileFormatException(String gripe){
        super(gripe);
}
}
  • 现在就可以抛出自己定义的异常类型了
String readData(BufferedReader in) throw fileFormatException{
    ...
        while(...){
            if(ch==1){
                if(n<len)
                    throw new FileFormatException();
            }
            ...
        }
    return s;
}

7.2 捕获异常

  • 想要捕获一个异常,必须设置try/catch语句块
try{
    
}
catch(ExceptionType e){
    
}
  • 如果在try语句块中的任何代码抛出了一个在catch子句中说明的异常类那么:
  • 程序将跳过try语句块的其他代码
  • 创徐将执行catch子句中的处理器代码
  • 没有异常,将不执行catch
  • 如果抛出一个未声明的异常类型,那么方法会立即退出
  • 如果想传递一个异常,就必须在方法的首部添加一个throws说明符,告知调用者这个方法可能会抛出异常
  • finally要是包含return语句时,在方法返回前会执行finally子句,将会覆盖返回值

7.3 使用异常机制的技巧

  • 异常处理不能代替简单的测试
  • 不要过分地细化异常
  • 利用异常层次结构
  • 不要压制异常
  • 在检查错误时,苛刻要比放任好
  • 不要羞于传递异常

7.4 记录日志

  • 基本日志:使用全局日志记录器,并调用info方法
  • 高级日志:调用getLogger方法创建或获取记录器
private static final Logger myLogger =logger.getLogger("com.mycompany.myapp");

注意:未被任何变量引用的日志记录器都可能被垃圾回收。所以用一个静态变量存储日志记录器的一个引用

  • 日志级别
  • SEVERE
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINSET

第八章 泛型程序设计

8.1 好处

  • 使代码有更好的可读性和安全性

8.2 定义简单泛型类

  • 类型变量使用大写形式:使用E表示集合的元素类型,K和V分别表示标的关键字和值类型,T、U、S表示任意类型

8.3 泛型方法

  • 当调用一个泛型方法时,在方法名前的尖括号中放入具体的类型。
public class promble {
   
    public static <T> void getamx(T a){
        System.out.println(a);

    }

    public static void main(String[] args) {
        getamx("dasda");
        promble.<String>getamx("sdadada");
    }
}

8.4 类型变量的限定

  • 可以通过对类型变量T设置限定
public static <T extends Comparable> T min(T[] a)

8.5 泛型代码和虚拟机

  • 虚拟机中没有泛型,只有普通的类和方法
  • 所有的类型参数都用它们的限定类型替换
  • 桥方法被合成来保持多态
  • 为保持类型安全性,必要时插入强制类型转换

8.6 约束与局限性

  • 不能用基本类型实例化类型参数
  • 运行时类型查询只适用于原始类型
  • 不能创建参数化类型的数组
  • Varargs警告
  • 不能实例化类型变量
  • 不能构造泛型数组
  • 泛型类的静态上下文中类型变量无效
  • 不能抛出或捕获泛型类的实例
  • 可以消除对受查异常的检查
  • 注意擦除后的冲突

8.7 通配符类型

  • 通配符类型中,允许类型参数变化
  • Pair<? extends Employee>
  • 通配符的超类型限定,可以指定一个超类型限定
  • 无限定通配符

8.8 反射和泛型

  • 泛型Class类
  • 使用Class参数进行类型匹配
  • 虚拟机中的泛型类型信息

第九章 集合

9.1 Java集合框架

  • 将集合的接口与实现分离
  • Collection接口:基本接口
  • 基本方法:
  • add()添加元素
  • Iterator():用于返回一个实现类Iterator接口的对象
  • 集合框架中的接口
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bh6D39Wj-1582015998644)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200218095021.png)]

9.2 具体集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sd6bm9sg-1582015998644)(C:\Users\sunmingzhi\AppData\Roaming\Typora\typora-user-images\1581990667813.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vP7FYVy-1582015998645)(C:\Users\sunmingzhi\AppData\Roaming\Typora\typora-user-images\1581990690157.png)]

具体见博客

9.3 映射

  • Java库中HashMap和TreeMap都实现了Map接口,如果不需要按照排列顺序访问键,就最好选择散列

第十章 并发

10.1 线程

  • 不要调用Thread类或者Runnable对象的run方法。直接调用run方法,只会执行同一个线程中的任务,而不会启动新线程。应该调用Thread.start方法,这个方法将创建一个执行run方法的新线程

10.2 线程中断

  • interrupt()方法可以用来请求终止线程,当调用时线程的中断状态将被置位,但是当线程被阻塞就无法坚持中断状态。中断一个线程不过是引起它的注意,被中断的线程可以决定如何响应中断

10.3 线程状态

  • 线程的六种状态:可以使用getState查看
  • New新建
  • Runnable可运行
  • Blocked被阻塞
  • Waiting等待
  • Timed waiting计时等待
  • Terminated被终止

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1pW9vKF0-1582015998645)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200218102126.png)]

10.4 线程属性

  • 线程优先级
  • 守护线程
  • 未捕获异常处理器

10.5 同步

  • 有两种机制防止代码块受并发访问的干扰,synchronized关键字打到这一目的,并且Java SE 5.0 引入ReentrantLock类。其保护代码块的基本结构:
myLock.lock();
try{
    
}
finally{
    myLock.unlock();
}

其保证了任何时刻只有一个线程进入临界区。

  • 监视器特性:
  • 监视器值包含私有域的类
  • 每个监视器类的对象只有一个相关锁
  • 使用该锁对所有的方法进行加锁
  • 该锁可以有任意多个相关条件