Java核心技术笔记
Java核心技术读书笔记
第一卷:
名词解释:
- JIT编译器 解释到本地机器码 加速执行速度(JUST IN TIME)代替技术:hotspot
- Applet = web程序
- UML:类的三个关系:依赖、继承、聚合
- Jdk与jre:jdk=java development kit(面向开发者);jre=java runtime environment(面向使用者)
- JUnit为 常见的单元测试框架
- String.class是一个Class<String>类的对象
与C++区别:
- 字符串不可修改
- 字符串比较:equals函数
- Scanner可以控制输入 java.util.*包内
- 使用标准输入输出:System.out.print或者System.in(package java.util.*)
- 不允许嵌套的两个块中声明同名变量
- 带标签break 跳转到标签处
- Java没有运算符重载
- 声明数组 int[] a=new int[100];
- 特有的for each循环 例:for(variable:collection)statement: variable暂存变量 collection数组名
- 允许数组长度为0,允许匿名数组
- 数组拷贝使用系统函数System.arraycopy
- 类均是引用 返回的亦是引用,私有对象只能返回克隆 对象生成均需要用new;值拷贝和引用拷贝
- Date类
- Const方法 访问器和修改器基本无区别
- class与java文件
- final保证域值不被修改 即定义常量(const作为保留字);定义方法取消动态绑定 类似inline
- 不支持多继承
- static静态域=类域 一个副本 static静态域:static{}
- finalize方法是在垃圾回收器前调用 类似C++的析构器
- 包类似命名空间
- 包路径
- 标记 javadoc 注释抽取
- 动态绑定 子类的使用的方法没有 运行时搜索其超类的方法
- Protected安全性不同 所有子类及同一个包中其他类均可见
- @ovreride做标记 覆盖超类的函数
- 操作符== 只是判断对象引用是否相同
- 对基本类型打包,使用包装器wrapper
- 反射:分析类能力的程序 Class类:显示类的详细信息;Array类:数组长度和获取数组元素。获取Object相当于C++中的void*指针(运行时查看域和方法,不要过多使用)
- 使用toString方法查看类的内部信息 newInstance反射回信息
- 方法指针=函数指针(C++中) method invoke方法(在try内写)[实际使用考虑接口]
- 枚举类 注意初始化(对枚举对象赋值)和获取枚举数值。valueOf和toString
- 接口与抽象类的区别(多继承问题):接口中所有抽象方法,在子类中必须全部实现;抽象类则不需要。(接口为规范或成品,抽象类为半成品)。接口中所有方法均为public 使用instanceOf检查是否实现某接口(接口中域自动设定为public static final)
- 一个类可以实现多个接口
- 使用sort方法,需要实现comparableTo接口
- 标记接口:不用实现接口中的特定方法,用它进行instanceOf检查
- 拷贝类【深拷贝】(对象克隆):Cloneable接口类似C++中的拷贝构造函数 确保实现Cloneable接口
- 回调,指定时间发出通告
- JAVA嵌套类与C++嵌套类的区别:非static的嵌套类具有外部类对象的引用,方便读取外部类对象的状态
- 内部类可以通过引用使用外部类的参数
- 局部内部类=某个块域内的类 可访问外部类 还可访问参数(必须为final)
- 匿名类 内部类基础上去除类名
- 静态内部类:取消内部类对外部类的引用 接口中的内部类自动变为static和public
- 代理:减少桩代码 运行时创建给定接口的新类(Class对象不能实例化接口)
- 代理:指定接口中需要创建的全部方法并实现Object类的全部方法
- 代理:调用处理器,Object invoke(Object proxy, Method method, Object[] args)参数分别为[代理器,方法名,调用参数]
- 代理使得在程序运行过程中构建对象实例,并对调用方法进行处理(使用调用方法处理器)注:InvocationHandler为调用处理器接口只有invoke一个方法
- 新建代理器,newProxyInstance(类加载器,Class对象数组,可调用处理器)
- Applet和servelet 容器Container:Component派生下的一个子类,用于包含Window或Panel
- 沙箱:隔离的测试环境 防止applet程序探测用户信息
- Applet使用签名,给予其额外的权限
- Java web start 具有更强的沙箱功能
- JavaScript与java关系不大,网页内使用的脚本语言
- Java中存在URL类,分为绝对URL和相对URL
- Applet上下文:applet要求浏览器为它提供服务
- Beans:程序组件
- Jar文件包含类文件、程序资源文件和描述性清单文件
- Java中资源文件是独立于文件存储的,不是作为类文件的一部分;注意其与windows中资源区别
- 包的seal(密封):不允许其他类置于这个包中
- Java web start沙箱比较宽松 允许未签名应用程序访问本地资源
- JNLP(JAVA NETWORK LAUNCH PROTOCOL) 配置java web start的发布
- Tomcat为servelts和JSP的容器
- 配置文件格式*.mf 标明主类等
- 属性映射:存储KV对 Properties类扩展Hashtable类
- 异常对象都是有Throwable派生出的实例:Error和Exception(IO Exception和Runtime Exception)
- 子类抛出的异常范围小于超类异常范围
- Java中 throw说明符在编译时执行 不对throws说明 将不抛出任何异常
- 先在函数上声明异常(throws) 再在函数内部相应位置抛出异常(throw) 可使用已有异常类,也可使用自定义异常类 无捕获异常 程序会自动显示于控制台上
- 捕获异常 使用try/catch子句
- 异常链 注意包装异常 设置原始异常 将异常一级一级返回 至调用处
- finally子句 无论异常是否执行 都会执行该finally、子句 保证资源的正确释放
- 注意return情况(finally子句覆盖原有return语句)以及异常覆盖问题(try与finally中具有异常抛出[解决方法:finally子句不要抛出异常])使用try/catch和try/finally会使代码清晰
- 注意:java没有析构器
- 堆栈跟踪:跟踪抛出异常的语句 throwable对象调用getStackTrace方法
- 异常使用规则:1.异常处理不代替简单测试2.不过分细化异常3.利用异常层次控制4.不要压制异常5.有错误就抛出6.不羞于传递异常(传递异常好于捕获异常)
- 日志系统:可将日志显示在控制台中,或者直接输出到文件 可使用多个层级结构
- 日志系统的配置由配置文件控制 使用日志记录器记录系统的调用
- 日志系统会有日志记录级别(记录器和处理器)[StreamHandler FileHandler SocketHandler]
- 过滤器:按日志级别,对日志记录进行过滤
- 格式化器:产生文本文件或者XML文件
- 断言:加速测试,发布版本 该语句自动去掉
- 调试技巧:1.输出变量值(System或Logger)2.在测试类中书写main,测试类状态3.JUnit4.日志代理5.利用Throwable printStackTrace 错误写入System.err中6.类加载过程,-verbose7.jconsole
- 文件流与序列化
- InputStream和OutputStream(字节)派生流类 Reader和Writer(Unicode文本)
- 四个接口closeable flushable readable appendable
- 流过滤器的分层
- ZIP文件流
- 序列化:恢复对象流(读取对象格式->创建空白对象->数据填充)实现Serializable接口 方便恢复文件中的对象 而不需要过度关注存储对象的类型和数量
- 使用序列化保证对象持续性,保证对象读入读出均一个副本 (智能加载)(尤其针对网络传输)
- 使用transient标记不用序列化的值
- File文件即可以表示文件也可以表示路径
- 流 关注文件内容 File关注磁盘存储
- 考虑到序列化的性能,需要读写大量特定类对象,使用Externalizable接口
- NIO 新IO特性:内存映射文件、文件锁定、字符集编码和解码、非阻塞I/O
- 序列化自动补偿操作系统间的差异 保证不同机器间对象的拆分与重组
- NIO:内存映射文件较缓冲和随机存取快 NIO内存映射 为文件获取通道 Channel
- NIO:缓冲区数据结构
- NIO:文件锁定 防止多程序都去改文件
- 正则表达式:指定字符串模式 例如[+-]?[0-9]+|0[Xx][0-9A-Fa-f]+ 使用java.util.regex.*
- Java泛型中不适用template关键字
- 泛型方法:public static <T extends Comparable & Serializable> T min(T[] a){} //泛型类
- Java不存在代码膨胀 使用Object代替T
- 桥方法用来保证多态和泛型擦除
- 泛型类既不能抛出也不能捕获异常
- 泛型类中 例如Pair<S>和Pair<T> 即是S与T有继承关系 两个泛型实例也没有关系
- 通配符类型:Pair<? Extends Employee>指定类型参数为Employee子类 解决104点
- 无限定通配符:任意Object对象调用原始Pair类setObject方法
- 通配符捕获 再加个外层包 捕获无限定通配符
- 使用Class<T>参数进行类型匹配
第二卷:
名词解释:
守护线程:清理垃圾的线程
第一章 线程
- 实现一个Runnable接口,并重写run方法
- 任务数较多时,不为每个任务建立线程,而采用线程池
- 解除阻塞的线程,需要使用NIO中的通道机制
- 线程优先级不一定决定执行顺序 denpend on machine
- 守护线程: 为其他线程提供服务 setDaemon
- 线程组 ThreadGroup
- 线程同步 保证数据一致性 使用ReentrantLock 使用lock函数和unlock函数(try和finally间)(非一致性原因:寄存器存储)
- 条件对象Condition:管理已获得锁,却不能开始工作的线程 将锁的性质改为非互斥(允许多个条件变量进入)newCondition和await、signalAll
- 使用阻塞队列来完成同步 尽量不使用锁和条件变量 有可能可使用synchronized
- 同步块 synchronized(obj){}
- Volatile(免锁机制)
- 注意死锁
- 读写锁 优化读的共享
- 阻塞队列(java.util.concurrent): 提供同步的一种机制 具体见API 手册(线程安全的集合)
- 线程安全集合:高效队列和散列表
- ConcurrentHash能够保证不同线程插入同一条条目到缓存中 不重复(关联插入 和关联删除)
- 同步包装器 为集合提供线程安全
- Callable接口与Runnable区别 具有返回值 其中只有call方法
- 线程安全的集合使用ConcurrentLinkedQueue或ConcurrentHashMap
- 使用线程池 减少线程构建和销毁开销 ThreadPoolExecutor
- 注意区别Runnable Future和Callable
第二章 集合(Java为developer提供的一整套数据结构集合)
1.迭代器中 查找元素唯一方法:next()
2.Vector线程安全 ArrayList线程不安全
3.hashmap不是线程安全的 hashtable是线程安全的
4.注意:若需要比较两个object的大小 需要实现Comparator接口
5.树集用来存储有序的数据 hash用来存储无序数据 TreeSet
6.优先级队列 任意插入并排序 PriorityQueue
7.映射表 KV操作
第三章 顶点
后话:
C++与java区别
1. 运行速度
2. java无全局变量或函数 均在类中 若需要获得全局函数 考虑static置入类中
3. 无作用域运算符
4.