《Java学习笔记(第8版)》学习指导
目录
- 图书简况
- 学习指导
- 第一章 Java平台概论
- 第二章 从JDK到IDE
- 第三章 基础语法
- 第四章 认识对象
- 第五章 对象封装
- 第六章 继承与多态
- 第七章 接口与多态
- 第八章 异常处理
- 第九章 Collection与Map
- 第十章 输入/输出
- 第十一章 线程与并行API
- 第十二章 Lambda
- 第十三章 时间与日期
- 第十四章 NIO与NIO2
- 第十五章 通用API
- 第十六章 整合数据库
- 第十七章 反射与类加载器
- 第十八章 自定义类型、枚举
- 补充:Java网络编程
- 补充:Java安全
- 补充:Android开发
- 术语对照
图书简况
林信良(网名:良葛格,网站)的《Java学习笔记(第8版)》是我们《Java程序设计》课程的教材,封面如下:
Java的教材不少,除了内容深入浅出,这本书最大的优点是更新比较及时,第八版针对Java SE 8新功能全面改版,无论是章节架构或范例程序代码,都做了重新编写与全面翻新。我们课上从第6版就开始用它作教材,这本书总结了作者多年来的教学实践经验,汇集了学员在学习课程或认证考试中遇到的概念、操作、应用等问题及解决方案。
教材中的一些问题:
- 术语与大陆不一样,参考我总结的「术语对照」,书中大部分术语有了转换,但没有完全转换
- 改版后有些内容该删除没有删除,比如p497 关于Date和Calendar那段总结
- 有些代码存在一些问题,比如P64 Shift.java
考虑到大家这学期也在学习《数据结构》,我另外一门课程《程序设计与数据结构》 课程教学》的教材《Java程序设计与数据结构教程(第二版)》供大家学习参考。在《程序设计基础》和《Java程序设计》中学习编程;在《数据结构》中学习高效编程;在《安全软件工程》或《安全编程技术》中学习安全高效编程;这是信息安全专业的专业进取路径。
返回目录
教材导读
Windows下Java开发环境,对于初学者推荐「JDK + Vim + PowerCMD」。如果感觉学Vim有点困难,初期可以使用「JDK + jEdit + PowerCMD」或「JDK + NotePad++ + PowerCMD」。
Linux下Java开发环境,对于初学者推荐使用「Git+Openjdk+Vim」.在Ubuntu14.10后的版本中的安装命令是:
sudo apt-get install git
sudo apt-get install vim
sudo apt-get install openjdk-8-jdk
旧版本的Ubuntu中安装openjdk8, 参考How to Install OpenJDK 8 in Ubuntu 14.04 & 12.04 LTS.
如果你用的是MacBook的macOS操作系统,就不用安装Ubuntu虚拟机了,把macOS当Linux用就行了。
对于IDE(Integrated Development Environment,集成开发环境),图书上使用的是NetBeans,考虑到我们课程会涉及到Android开发,而用于Android开发的IDE Android Studio(CN)是在Intellij IDEA上构建的,所以我们上课推荐的IDE是Intellij IDEA。
Intellij IDEA是收费软件,但对学生免费,可以到这里申请免费使用。
这里有IDEA的使用教程,包括不少视频教程。IDEA的使用过程中要慢慢掌握常用的快捷键(哪个常用就刻意记忆一下,参考十大Intellij IDEA快捷键).IDEA的快捷键如下图所示:
其他工具和教程参考「程序开发与信息安全工具箱」。
课程相关信息参考「《Java程序设计》 课程教学」。
相关链接
- 图书范例下载:
- 大陆-清华大学出版社-电信
- 大陆-清华大学出版社-铁通
- 台湾
注意,这些代码都要求同学们自己一行一行的输入,运行,调试;提供下载链接主要是方便在遇到一些自己找不到的错误时对照用,千万不要把代码拷贝过去编译运行一下就完了,这样基本上什么也学不到!!!
参考代码驱动的程序设计学习中的「git的安装测试」部分,建立与教材配套的目录结构,目录要体现出自己学号姓名
,如下图所示:
- Java 认证
返回目录
第一章 Java平台概论
1.1 Java不只是语言
- 了解Java的历史
- 为什么需要Java程序设计语言?
- Java解决了什么问题?
- 识记Java三大平台:
- Java SE(Java 2 Platform Standard Edition)
- Java EE(Java 2 Platform Enterprise Edition)
- Java ME(Java 2 Platform Micro Edition): 不用学了,学Android就好
- Java SE的四个组成部分
- JVM,JRE,JDK与Java语言
- 学习Java API的重要性
- 了解JCP与JSR、RI、TCK的关系
- 了解Oracle JDK与OpenJDK的关系
- 了解Java的学习路径,参考Java Technology Concept Map
- 深入理解JVM/JRE/JDK
- JVM是Java程序唯一认识的操作系统,其可执行文件为.class文件
- PATH与CLASSPATH
- 面向对象技术
- 封装
- 继承
- 多态
- Java API: 从父类学起,注意继承体系
- 容器
- p11讲的「容器(Container)」的观念非常重要。
- 研究源码
- JDK安装时选上源代码,安装后在JDK的安装目录下会有一个src.zip:
- Java官方demo是学习的好资源
- JDK安装时选上源代码,安装后在JDK的安装目录下会有一个src.zip:
- 学习设计模式和重构
- 模式是专家经验的总结,想学习设计专家的经验就要学习设计模式,在面向对象的学习中,设计模式和面向过程中的数据结构和算法的地位一样重要
- 重构是不改变功能的前提下改善程序结构,现在的Java开发IDE如NetBeans,Intellij IDEA中都有一个菜单项
Refactor(重构)
,你就理解重构的重要性了。
- 深入理解JVM/JRE/JDK
- 思考题:
- 这一节的标题是「Java不只是语言」,学完这节内容后你认为Java还是什么?
1.2 JVM/JRE/JDK
「Java Conceptual Diagram」
- 理解JVM是执行Java程序(可执行文件*.class)的操作系统(或容器)
- 理解JVM是Java实现「一次编译、到处运行」的跨平台的关键
- JVM负责Java程序的各种资源管理
- 理解JVM、JRE与JDK的关系
- JRE用来部署Java程序,包括Java SE API和JVM
- JDK用来开发Java程序,包括Java程序设计语言、JRE和开发工具
下载、安装JDK,理解「Public JRE」和「Private JRE」的用途
- 思考题:
- 只执行Java程序,不下载JDK可以吗?
相关链接
- Java 版本与CodeName
- Tony Targonski的「If a programming language was a boat…」
- JCP
- JDK7 RI
- JDK8 RI
- Java6 规范
- Java7 规范
- Java8 规范
- Java 官网
- OpenJDK 官网
- Servlet/[email protected]
- Java EE Container
- Junit 研究
- JDK下载
- Java SE - Change in Version Numbering Scheme
- Java8 Documents
- Java8 API
- The Java Tutorial
拓展
- Oracle Java
- Java White Paper
- JUnit官网
返回目录
第二章 从JDK到IDE
2.1 从Hello World 开始
- 使用命令行和IDE两种方式编辑、编译、运行「Hello World」程序,一旦可以运行「Hello World」程序,就说明你建好了Java 开发环境,并且有很大的成就感,之后完全就可以参考「积极主动敲代码,使用Junit学习Java程序设计」来学习了。可以看看「实验一 Java开发环境的熟悉」。
- 在Window下学习Java开发,参考一下「Java程序设计的DOS命令基础」
- 在Unix/Linux下学习Java开发,参考一下「别出心裁的Linux命令学习法」
- 理解
PATH
是用于Windows/Unix/Linux等系统的,找不到javac.exe
、java.exe
是因为PATH
没有设置正确 - 理解
CLASSPATH
是用于JVM(容器)的,使用javac
和java
命令找不到XXXX.class
是因为CLASSPATH
没有设置正确 - 理解「JVM是Java程序唯一识别的操作系统,对JVM来说,可执行文件就是扩展名为
.class
的文件」 - XXXX.class的路径可以用
java -cp
或java -classpath
指定,此时就不用设定CLASSPATH
环境变量了 编译、运行p31的
Main.java
,其中相关的Console.java
的内容是:public class Console { public static void writeLine(String text) { System.out.println(text); } }
- 思考题:
- 编译、运行「Hello World」时你遇到了什么问题?怎么解决的?(参考)
2.2 管理源码与二进制文件
- 理解
SOURCEPATH
和-d
的作用,编译带有package
语句的Java代码时,必须使用javac -d outpath XXXX.java
掌握
package
和import
的使用,会用命令行编译、运行带有package
和import
语句的Java代码- 思考题:
- 版本控制只要源码,不要生成的二进制文件(.class),git中怎么做?
2.3 使用IDE
- 会用IDE(IDEA、Netbeans、Eclipse等)编译、运行、调试Java代码
- 项目管理
- src:源码
- classes/out:编译输出class,
- docs:项目相关文档
- lib:第三方jar
- test:测试代码
- ...
- 调试(参考「实验一 Java开发环境的熟悉」中的调试部分)
- 断点的设置(行断点、函数断点、临时断点、条件断点)
- 单步执行(step over/step into,优先使用step over)
- 查看变量的值
- ...
- 项目管理
学会使用
java -version
和java -verbose XXXXClass
诊断问题- 思考题:
- IDE中
PATH
和CLASSPATH
怎么体现?以你使用的IDE(IDEA、Netbeans、Eclipse...)举例说明
- IDE中
- 完成课后练习
- 选择题
- 1-4 有关main函数
- 5-10 CLASSPATH、package、import,第8题一定要理解
- 选择题
动手:
- 编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
相关链接
- Path是什么?
- CLASSPATH是什么?
- 鸡生蛋?蛋生鸡?
- Jar文件中的源文件和类文件
- JUnit Gossip
- 认识Gradle
- Ant下载
- Maven下载
- Gradle下载
- NetBeans下载
- Intellij IDEA下载
- Eclipse下载
- The Class File Format
- The Java Virtual Machine Specification
返回目录
第三章 基础语法
3.1 类型、变量与运算符
- 类型
- 基本类型
- 整数(short、int、long)
- 字节(byte)
- 浮点数(float/double)
- 字符(char):汉字、英文字符都是双字节的,Java字符编码是
Unicode6.2.0
,JVM编码是UTF-16 Big Endian
- 布尔(boolean):boolean类型中的true/false不能与其他类型进行运算
- 类类型
- 基本类型
- 注释
- 三种注释
- //:单行
- /**/:多行
- /** */:javadoc文档注释
- 为何要注释
- 简洁的点明程序的突出特征或是提供一种概观,帮助别人理解程序,提高程序的可读性
- 注释为什么(why),不要注释做什么(what),伪代码是最好的注释(参考「实验二 Java面向对象程序设计」)
- 注释注意事项
- 给函数和全局数据加上注释
- 要澄清情况,不要添乱子
- 不要大谈明显的东西
- 不要注释差的代码,重写它
- 不要与代码矛盾(javadoc)
- 否定之否定规律
- 最好和最差的代码都不需要注释
- 三种注释
- 变量
- 注意Java中变量名的
Camel Case
命名法 - 常量定义用
final
修饰 - 命名符合
min-length && max-information
,不要用汉语拼音命名,参考Naming Conventions和Google Java Style。 - 局部变量使用前要初始化
- 注意Java中变量名的
- 字面常量(Literal constant)
- 整数可以用二进制(0bdddd),八进制(0ddd)、十进制(dddd)、十六进制(0Xdddd),Java中都是有符号下整数,没有
unsigned int
之类 - 浮点数科学计数法
- 小数(如1.4)默认类型是
double
,1.4f
或1.4F
的类型才是float
- 字符可以用Unicode 字符编码(Code Point)来表示。参考「字符编码」。
- Java SE7 后可以用下划线分隔数字,如:123_456,3.141_592_653,0b1010_0011.
- 整数可以用二进制(0bdddd),八进制(0ddd)、十进制(dddd)、十六进制(0Xdddd),Java中都是有符号下整数,没有
- 运算符
- 算术运算
- +
- -
- *
- /
- %: 密码学上常用
- 关系运算:注意不要对浮点数进行相等性运算,可以试试
1.0-0.7==0.3
?- >、>=、<、<=、==、!=
- Conditional Operator: 条件表达式 ? 成立时返回值:失败时返回值
- 逻辑运算:运算结果是boolean值:true Or false
- 与(&&)
- 或(||)
- 非(!)
- 位运算 :运算结果为位串(位向量),常用于掩码(Mask)运算
- 与(&):全1为1,有0则0
- 或(|):全0为0,有1则1
- 非(~):书上说是
补码
,按我们的习惯应该是反码
- 异或(^):相同为0,不同为1
- 左移(<<):最右补0
- 算术右移(>>):右移后,正数最高位补0,负数最高位补1
- 逻辑右移(>>>):右移后,最高位总是补0
- 递增、递减
- i++,i--
- ++i,--i
- 赋值
- =
- +=, -=, *=, /=, %=,&=, |=, ^=, <<=, >>=
- 算术运算
- 类型转换
短->长
(widening)是安全的,长->短
(narrowing)必须强制转换
- 表达式中含不同类型,以长度最长的为准,其他的会进行类型提升(Promote)
3.2流程控制
- Structured programming(结构化程序设计)包含三种语句
- 顺序:计算机结构决定语句是顺序执行的,正常情况下都是顺序执行的
- 分支:分支用来处理异常情况的
- 循环:执行最常用的语句,这是计算机的特长
- 分支
- 类型
- if
- if...else
- if...else if
- switch...case
- switch可用于整数、字符、字符串、Enum
- default
- 分支的各种情况要满足
不重复,不遗漏
的原则,即:「MECE」(Mutually Exclusive Collectively Exhaustive,相互独立,完全穷尽)- 分支可以用查表简化,示例:一个月有多少天?
int daysPerMonth[12]={31,28,31,30,31,30,31,31,30,31,30,31} int daysOfTheMonth(int month){ return daysPerMonth(month-1); }
- 类型
- 循环
- 类型
- for
- while
- do...while
- break/continue
- 配合标签可以实现
goto
的效果 goto
可用于从多重循环是跳出来
- 配合标签可以实现
- 类型
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
不少都是代码段,自己新建一个
TestJavaBasic.java
的类,把代码段输入进行测试,比如p57代码:public class TestJavaBasic { public static void main(String[] args) { p57test(); } public static void p57VariableTest(){ int number = 10; double PI = 3.14; System.out.println(number); System.out.println(PI); } }
- p55 Range.java: Java基本类型的范围
- Byte与byte什么关系?其他类型呢?
- printf的各种格式控制符号怎么使用?找一种自己没有用过的测试一下。参考p65 表3.1和Formatter
- P69 Comparison.java: 关系运算
- P62 Bitwise.java: 位运算
- 理解位运算的结果是位串(位向量)
- 尝试增加代码,测试多个位的运算,比如:0xABCD & 0xF0F0
- 设计几个掩码,比如:把一个整数的某个位清零,把一个整数的某个位清零
- p64 Shift.java: 移位
- 理解好位运算对密码学的学习有帮助
- 这个程序的运行结果跟教材中一样吗?
- p69 Odd.java: if...else
- p71 Level.java
- 符合「MECE」吗?
- score = 100,结果如何?
- score = 120,结果如何?
- 代码效率如何?怎么改进?怎么证明有改进?
- p73 Level2.java: switch
- 代码有问题吗?
- p74 OneToTen.java: for
- p74-p75 NineNiteTable.java NineNiteTable2.java
- 如何去除重复的内容?
1*1= 1 1*2= 2 2*2= 4 1*3= 3 2*3= 6 3*3= 9 1*4= 4 2*4= 8 3*4=12 4*4=16 1*5= 5 2*5=10 3*5=15 4*5=20 5*5=25 1*6= 6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36 1*7= 7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49 1*8= 8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64 1*9= 9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
- p76 RandomStop.java RandomStop2.java
- random()的值的范围?你怎么获得的?
- 思考题:
- 有关基础语法,Java和C有什么异同?
课后练习
+ 选择题
+ 实现
相关链接
- 哪来的纯文本文件?
- Unicode与UTF
- 乱码
- Formatter
- Java Naming Conventions
- Google Java Style
- Code Conventions for the Java TM Programming Language:官方代码规范
- Google Style Guides(中文版)
- Promotion与Cast
拓展
- 参考程序设计实践(The Practice of Programming) 第一章
返回目录
第四章 认识对象
- 对象(Object):存在的具体实体,具有明确的状态和行为
- 类(Class):具有相同属性和行为的一组对象的集合,用于组合各个对象所共有操作和属性的一种机制
- 从类看对象:类定义可以视为一个具有类似特性与共同行为的对象的模板,可用来产生对象
- 从对象看类:类的产生,是从少数实例,推广到大量相似实例的抽象化过程(abstraction)
- 类是对象的设计图,对象是类的实例,生成对象要先定义类
4.1 类与对象
- 理解p84页的图4.1,
Clothes c1 = new Clothes();
- c1是引用,在栈上
- new Clothes()在堆上生成对象
- c1 可以近似看成指向对象的指针
- 在《数据结构》中实现链表,C语言使用指针,Java使用引用
- 养成
一类一文件
的的习惯- 一个类
XXXX
写到一个XXXX.java
的习惯- public class XXXX{}
- 尽量不要在一个类中写多个class,如果有多个class,也只能有一个类前面加
public
- 一个
XXXX.java
要有一个包含main函数的XXXXTester.java
的测试类
- 一个类
- 构造方法决定类生成对象的方式
- this
- new
封装 = 类 + 访问控制(public,protected,private...)
- java.util.Scanner与java.math.BigDecimal
- 参考「积极主动敲代码,使用Junit学习Java程序设计」
- 注意类的构造方法
- Scanner类大大简化了Java的输入,要熟练掌握其方法,关键是会查API文档,能自学
- 对象相等
- == 与 equals的区别
- ==比较的对象的地址
- equals 是逻辑上相等
- 参考教材图4.1就容易理解了
- == 与 equals的区别
4.2 基本类型包装
- 为了让Java 基本类型像类一样使用
- int-Integer
- long-Long
- byte-Byte
- float-Float
- double-Double
- boolean-Boolean
- ...
- 理解Autoboxing和Unboxing
- Autoboxing和Unboxing是编译器语法糖
4.3 数组对象
- Java中,数组是对象
- 与C语言不同,Java检查数组边界,越界会触发
ArrayIndexOutOfBoundsException
异常 - 数组访问的
foreach
语法 - 理解图4.5、4.6、4.7、4.8
- System.arraycopy()与Arrays.copyof()
- javac -encoding 指定字符编码
- 思考题:
- 举例说明什么是浅拷贝与深拷贝?
- 你遇到过乱码的情况没?有的话如何解决问题的?
4.4 字符串对象
- String/StringBuffer/StringBuilder
- 参考「Java:String、StringBuffer和StringBuilder的区别」,特别是其中的「使用策略」
- 参考「java中String、StringBuffer、StringBuilder的区别」
- 思考题:
- C语言中怎么实现数字与数字字符串的互换,如:123->“123”, “123”->123
- int atoi(const char *nptr);// aoti("123")->123
- char itoa( int value, char string,int radix);// itoa(123, str, 10)->"123", str=="123"
- Java中怎么实现数字与数字字符串的互换,如:123->“123”, “123”->123
- int atoi(String nptr)
- String itoa(int value, int radix)
- C语言中怎么实现数字与数字字符串的互换,如:123->“123”, “123”->123
4.5 查询API文档
有人用Visual Studio学完C语言后,竟然不知道MSDN。遇到问题不知道去哪寻找答案。
学习Java,同样要学会使用Java API,在Windows下一定要下载CHM格式的Java API,这个版本具有检索功能,使用非常方便。
如何利用Java API来学习,参考「积极主动敲代码,使用Junit学习Java程序设计」。
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
不少都是代码段,自己新建一个
TestJavaClass.java
的类,把代码段输入进行测试,如p87页代码:public class TestJavaClass { public static void main(String[] args) { p87TestFloatEquals(); } public static void p87TestFloatEquals() { double a = 0.1; double b = 0.1; double c = 0.1; if ((a+b+c) == 0.3){ System.out.println("等于0.3"); } else { System.out.println("不等于0.3"); } } }
- p84 Field.java: 访问对象的成员变量
- sun == spring?
- 与C语言结构体做比较
- p85 Field2.java: 构造方法的使用,构造方法决定了生成对象的方式
- 构造方法的参数与类成员变量一样,通过this区分
- 加一行
Clothes2 autumn = new Clothes2();
能编译、运行吗?为什么?
- p86 Guess.java: Scanner
- 类比C语言的
scanf
- 查API文档,学习测试相关API
- nextXXX()的使用
- next()
- nextLine()
- 修改代码,测试学习效果,比如增加代码,完成「打印两遍自己输入的字符串」的功能
- 类比C语言的
- p88 DecimalDemo.java: BigDecimal
- 运行结果和你想象的一样吗?如果不是问题在哪?
op1.add(op2).add(op3).equals(result)
是什么用法?- 查API文档,学习测试相关API
- plus()
- substract
- multiply
- divide
- 修改代码,测试学习效果,比如打印两个整数的乘积
- 挑战一下自己,完成一个实用软件。参考「小学四则运算题目软件」
- p91 IntegerDemo.java: Wrapper
- 查Java API文档,学习测试Integer类的其他方法,并写代码测试
- 查Java API文档,学习测试其他Wrapper类(Long,Double,Float,Boolean...),并就其中一个写代码测试
- p96 Score.java: for遍历数组
- 0-length-1
- 使用foreach改写代码
- p97 XY.java :二维数组
- 外层循环获得行数(row),内层循环获得列(column)
- 使用foreach语法改写代码
- p98 Score2.java: Arrays类
- 查API文档,学习测试Arrays类相关的API
- 把scores填充成{55,65,65,80,75,70,95,90,85,100},测试一下Arrays类的各种排序方法
- p101 IrregularArray.java: 不规则数组
- 二维数组声明要给出行数(代码中int[2][])
- p102 IntegerArray.java: 对象数组 (用类声明的数组)
- 先想一下结果,看看实际是不是这样
- 理解图4.10,4.11
- p104 CopyArray.java: 数组复制
- 怎样证明修改score2不影响score1
- p105 ShallowCopy.java: 对象数组浅拷贝
- 先想一下结果,看看实际是不是这样
- 理解图图4.12
- p106 DeepCopy.java: 对象数组深拷贝
- System.arraycopy()和Arrays.copyOf()用在对象数组上都是浅拷贝
- 什么时候需要深拷贝?
- p108 Sum.java: 字符串转成数字
- parseLong的功能?
- nextLine的功能?
- 输入11.1试试,会是什么效果?如果有问题怎么解决?
- p109 Average.java: 命令行参数
- args数组的功能?
- 怎么获取命令行参数的个数?
- C语主和Java的main函数的命令行参数有什么不同?
- IDE中怎么传命令行参数?
- p112 OneTo100.java: StringBuiler
- 参考第十三章,教材上打印1-100的几种方式的效率怎么测试?假设打印100000遍
课后练习
- 选择题
- 1-3:boxing unboxing,不运行试试很可能做不对
- 4-5: 数组概念
- 6-10:String
- 实现题
- Fibonacci
- 递归:递归公式,终止条件
- Java中能求的最大的Fibonacci数是多少?
- 洗牌
- 随机数的应用
- 排序:Arrays.sort
- 查查《数据结构》课程教材
- 查找:Arrays.binarySearch
- 查查《数据结构》课程教材
- Fibonacci
相关链接
- 1.0-0.8 不是 0.2?
- 我们没什么不同
- Google Java Style
- NotePad++ 下载
- Java API下载(CHM格式)
返回目录
第五章 对象封装
5.1 何谓封装
- 封装(Encapsulation)实际上使用方法(Method)将类的数据隐藏起来,控制用户对类的修改和访问数据的程度,隐藏对象细节,将对象当作黑箱进行操作
- 通过
构造方法(构造函数)
封装初始化流程
- 通过
成员方法(函数)
封装操作
- 通过
成员变量
封装数据
- 通过
- 封装与SRP原则
-
- 参考实验二 Java面向对象程序设计中的「S.O.L.I.D」原则
-
- 封装的好处
- 模块化(Modularity)
- Source code independence
- Object Passing
- 信息隐藏(Information hiding)
- 对象内部的状态被保护起来了,不会被与该对象沟通的对象直接修改
- 对象内部特征的变化不会改变与其他对象沟通的方式
- 模块化(Modularity)
5.2 类语法细节
- public
- 用在类前
- 用在方法前
- 用在成员变量前
- private
- 用在类前,可以吗?
- 用在方法前,可以吗?
- 用在成员变量前
- 方法重载(Overload)
- 参数类型和个数不同
- 与返回值无关(why?)
- this与super
- final
- 用在类前
- 用在方法前
- 用在成员变量前
- static:所有对象公有的
- 用在类前
- 用在方法前
- 用在成员变量前
- 访问惯例:
类名.static成员
- 与C语言中的static区分
- import static 的用法
- 变长参数
- 内部类
- Java中方法都是传值(Pass By Value)的
- 传值(Pass By Value,Call by Value)
- 传引用(Pass By Reference,Call by Reference)
- 对比C语言中的传值,传指针,想想swap如何实现
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaEn.java
的类,把代码段输入进行测试 - p124 CashCard.java, CardApp.java: 封装构造过程
- CardApp相当于CashCard的测试类
- 养成对XXXX.java写TestXXXX.java的习惯,不要把产品代码和测试代码混在一起,有类的设计者和类的使用者分开的意识
javac *.java
可以编译多个java源文件
- p126 CashCard.java, p128 CardApp.java: 用方法(函数)封装操作
- DRY(Don't Repeat Yourself)是去除重复代码的有效手段
- 使用函数符合DRY(Don't Repeat Yourself)原则
- 体会代码量的大幅减少
- p129 CashCard.java: private成员封装数据
- 体会把对象当黑箱
- 从类的设计者和类的使用者体会封装的好处
- 修改 CardApp.java测试代码
- getter,setter IDE都可以产生,找一找怎么做
- p131 CashCard.java: 方法(函数)用public公开
- p135 OverloadBoxing.java: 方法(函数重载)
- p137 ObjectInitialBlock.java: 初始化块
- 初始化块在构造方法前执行
- p144 ImportStatic.java: 测试import static语法
- p145 MathTool.java: 变长参数
- 函数有多个参数,变长参数必须是最后一个
- p148 CallByValue.java: 传值调用
- 参考p149 图5.16,5.17,5.18,5.19好好理解
课后练习
- 选择题
- 1-7:构造方法,不运行试试很可能做不对
- 8,10: 变长参数,仔细看题
- 9: 重载顺序
- 实现题
- 汉诺塔
- 迷宫
- 棋
- 八皇后
相关链接
- C++ 函数参数的传值、传引用
- C++ 函数返回值的传值、传引用
- C/C++ 的变长参数
- Java Call by Value?
- Singleton 模式
返回目录
第六章 继承与多态
6.1 何谓继承
- 继承也符合DRY(Don't Repeat Yourself)原则
- ISA与OCP原则,LSP原则
- 参考实验二 Java面向对象程序设计中的「S.O.L.I.D」原则
- 赋值: 「=」 右边 ISA 左边,否则要强制类型转换
- Role role1 = new SwordsMan()
- SwordsMan swordsman = role1; //x
- SwordsMan swordsman = (SwordsMan)role1; //ok
- 注意ISA是指功能上的
- extends
- Java中只有单一继承,也就是只能有一个父类
- 要实现C++中的多重继承,要使用第七章中的「接口(Interface)」
- UML
- 多态
- 继承可以复用代码,更大的用处是实现「多态」
- 封装是继承的基础,继承是多态的基础
- 「用父类声明对象引用,用子类生成对象」就有了多态
- 覆盖(Override)
- 区分重载(Overload)
- Annotation:@override
- 抽象方法、抽象类
- abstract
- Java中有抽象方法的类一定是抽象类,但抽象类中的方法不一定都是抽象方法
- 抽象类不能使用new生成对象
- 思考题:
- Square(正方形)类继承Rectangle(矩形)类合适吗?
6.2 继承语法细节
- public/package/protected/private
- super与this
- java.lang.Object
- toString
- equals
- hashCode
- instanceof
- 垃圾收集(Garbage Collection,GC)
- 无法通过变量引用的对象就是GC认定的垃圾对象
- 垃圾回收前会调用finalize()方法,但由于调用时机无法确定,建议不要使用finalize()方法
- 设计模式
- 参考实验二 Java面向对象程序设计中的「模式」
动手:
- 编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaInheritance.java
的类,把代码段输入进行测试 - p158 SwordMan.java Magician.java: 两个类有重复代码,DRY,继承
- 定义好成员变量,getter/setter 可以由IDE生成
- 参考实验二 Java面向对象程序设计中的「重构」,找合适的IDE试试
代码提升(Pull Up)
- 图6.1使用UML的类图,参考实验二 Java面向对象程序设计中相关内容学习
- p159 Role.java: 定义父类
- p160 p161 SwordMan.java, Magician.java RPG.java: 继承消除重复代码
- RGP.java 是测试代码
- p165 RGP.java: ISA
- 函数参数用声明用父类,实参可以传子类
- 代码具有灵活性
- p167 Role.java SwordMan.java Magician.java RPG.java: 覆盖
- p169 Role.java : 抽象类
- p171 Role.java Swordman.java Magician.java : protected
- p173 Role.java Swordman.java Magician.java : 覆盖toString
- 以上四个代码只要在原来基础上稍微改改,然后通过运行代码理解相关知识点
- p178 ArrayList.java : Object类的应用
- p179 Guest.java是自定义ArrayList的测试类
- p181 Cat.java :注意如何覆盖equals
- 如何写Cat的测试类,让各个return都能访问到
- p185 Guess.java : 抽象类
- OCP带来的灵活性
- p186 GuessGame.java
- p187 ConsoleGame.java
- p187 Guess.java: 测试类
- 体会「计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决」
课后练习
- 选择题
- 1-5: 覆盖
- 6: 抽象类、抽象方法
- 7-10: this,super
- 实现题
- 覆盖toString
- 覆盖equals
- 先看看是不是和自己比较,自己与自己比较肯定相等
- 再看看是不是本类或子类(instanceof),不同类肯定不等
- 然后定义逻辑上的相等
- 覆盖equals()一定要同时覆盖hashCode()
相关链接
- 多态的本质(三)思考行为外观的次态多态
- 对象相等性
- 对象终结者
- javaword 之finalizers
- 设计模式
返回目录
第七章 接口与多态
7.1 何谓接口
- 接口(interface)定义行为
- implements
- 解决需求变更
- OCP原则,ISP原则:参考实验二 Java面向对象程序设计中的「S.O.L.I.D」原则
- 参考「代码的抽象三原则」,代码怎么样才能有弹性又不过度设计
- 思考题:
- 接口与抽象类的别?
7.2 接口语法细节
- 接口中的
public abstract
可以省略 - 接中可以使用extends继承接口,并且可以继承多个接口
- 匿名内部类与Lambda
- JDK8 前在匿名内部类中访问局部变量,则该局部变量必须为final
- emum
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaInterface.java
的类,把代码段输入进行测试 完整的代码学习前几章的方法,多提几个问题。
课后练习
- 选择题
- 实现题
相关链接
无
面向对象技术深化
- 参考实验二 Java面向对象程序设计
敏捷开发技术
- 参考实验三 敏捷开发与XP实践
- 参考- 极简单元测试示例(以除法为例)
返回目录
第八章 异常处理
前面Java核心和面向对象思想都讲解了,后面的内容都是使用Java的各种类库了,学习时注意面向对象思想在类库中的应用。
8.1 语法与继承架构
- 使用try...catch
- 与C语言中程序流程和错误处理混在一起不同,Java中把正常流程放try块中,错误(异常)处理放catch块中
- catch 多个异常
- API文档中带throws的必须使用try...catch,如下图
- 注意多个catch一定把父类放后面
- 异常架构
- Error及其子类写程序不用处理,最多留个日志
- Java异常处理是要处理
Exception
类及其子类(Checked Exception)RuntimeException
及其子类也不用处理(Unchecked Exception)- 产生
RuntimeException
的问题在调用代码 - 参考Design by Contract (DBC) 契约式设计
- Multi-catch:类之间不能有继承关系
- 学习Java API时一定对上层的类好好研究,学习,再学习和应用子类时就比较容易了
- catch or throw?
- throws:自己无法处理,用在方法声明
- throw:方法中抛出Checked Exception,方法声明中必须有throws
- 自定义异常
- 异常堆栈
- printStackTrace
- 善用堆栈追踪错误
- 代码中不要私吞异常
- 不要错误处理异常
- 处理时不要显示错误信息
- printStackTrace 和fillInStackTrace
- assert
- java -ea or java
- 什么时候使用断言
p244
8.2 异常与资源管理
- 使用finally
- try-catch-finally
- try with resources
- 关闭多个资源时用分号分隔
- java.lang.AutoCloseable
- try with resources的对象必须实现AutoCloseable接口
- 思考题:
- finally块中的代码一定会被执行吗?
动手:
- 编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaException.java
的类,把代码段输入进行测试 - p227 Average.java: 没有错误处理的
- 写出至少三个正常使用程序的测试用例(输入值,期望结果),看看期望与实际值是不是一样的
- 写出至少三产生异常的测试用例(输入值,期望结果),并回答下面问题
- 产生异常的原因在报错信息的什么位置?
- 引起异常的程序代码信息在哪一行?
- 程序出错就崩溃,体会错误处理的重要性
- p228 Average2.java: try...catch
- 与 Average.java比较,这个程序有什么优点
- p229 Average3.java: 有错误,如何回到正常流程
- 与 Average2.java比较,这个程序有什么优点
- p233 Average4.java: 使用正则表达式检查错误
- 参考正则表达式入门
- 信息安全专业的学生要学会使用正则表达式解决安全问题
- p236 FileUtil.java: throws,throw 抛出异常
- 写个带main的类测试一下
- p240 StackTraceDemo.java: 异常堆栈
- 最上层是产生异常的根本原因
- 以下是调用方法顺序,找代码原因可以从最下层开始找
- p242 StackTraceDemo2.java: 重抛异常,StackTrace仍然从产生处追踪
- p243 StackTraceDemo3.java: 使用fillInStacktrace重抛异常,StackTrace仍然从重抛处追踪
- p247 FileUtil.java: try...catch...finally
- p253 AutoCloseableDemo.java: 实现AutoCloseable接口
p253 AutoCloseableDemo2.java: try with resources关闭多个资源
编译、运行下面的代码,运行前自己先思考一下结果应该是什么
import java.io.IOException;
import java.awt.Button;
import java.util.Vector;
class ExceptionTest {
public static void main (String args[])
{
System.out.println("Entering main()");
ExceptionTest et = new ExceptionTest();
try {
System.out.println("Calling m1()");
et.m1();
System.out.println("Returning from call to m1()");
}
catch (Exception e) {
System.out.println("Caught IOException in main()");
}
System.out.println("Exiting main()");
}
public void m1() throws IOException
{
System.out.println("Entering m1()");
Button b1 = new Button();
try {
System.out.println("Calling m2()");
m2();
System.out.println("Returning from call to m2()");
System.out.println("Calling m3()");
m3(true);
System.out.println("Returning from call to m3()");
}
catch (IOException e) {
System.out.println("Caught IOException in " +
"m1()...rethrowing");
throw e;
}
finally {
System.out.println("In finally for m1()");
}
System.out.println("Exiting m1()");
}
public void m2()
{
System.out.println("Entering m2()");
try {
Vector v = new Vector(5);
}
catch (IllegalArgumentException iae) {
System.out.println("Caught " +
"IllegalArgumentException in m2()");
}
finally {
System.out.println("In finally for m2()");
}
System.out.println("Exiting m2()");
}
public void m3(boolean genExc) throws IOException
{
System.out.println("Entering m3()");
try {
Button b3 = new Button();
if (genExc)
throw new IOException();
}
finally {
System.out.println("In finally for m3()");
}
System.out.println("Exiting m3()");
}
}
课后练习
- 选择题
- 实现题
相关链接
- 避免隐藏错误的防御性设计
返回目录
拓展
- Java多线程之Runable与Thread
第九章 Collection与Map
Java实现的「数据结构」,可以和《数据结构》课程结合学习。
Collection:表示多个对象,多了才有研究算法效率的必要。
9.1 使用Collection集合对象
- 认识collection架构
- 再次体会先掌握父类再学习子类的好处
- 如何正确使用Collection API和《数据结构》课程学的如何有很大关系
- Connection: 增、删、遍历对象
- add
- remove
- clear
- size
- iterator
- List: 类似数组,具有位置信息,带索引
- 核心方法
- add(int index, E element)
- remove(int index)
- set(int index, E element)
- ArrayList
- 《数据结构》中的线性表
- LinkedList
- 《数据结构》中的链表
- 核心方法
Set: 其中的对象不能有重复的
- Queue: 队列
- 核心方法
- offer
- poll
- peek
- Deque: 双向队列
- 核心方法
- 注意区分泛型与继承
- Java的Collection API都支持泛型
- Lambda表达式
- 注意与匿名类相比的好处:DRY
- 参考第十二章
- Iterable与Iterator
- Iterator
- next
- hasNext
- Iterator
static void forEach(Collection collection) {
Iterator iterator = colleciton.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
static void forEach(Iterable iterator) {
for(Object o: iterable){
System.out.println(o);
}
}
- Comparable与Comparator
- sort:Java中对象排序,要么对象实现了Comparable可以直接sort要么提供Comparator对象告知sort如何排序
9.2 键值对应的Map
数组是用数字索引(Key),Map可以看作可以用非数字索引(Key)的数组
- 常用的Map类
- Dictionary与HashTable不建议使用
- Map
- put
- get
- size
- remove
- forEach
- HashMap
- TreeMap
- Properties:配置文件
- 访问Map键值
- keySet
- values
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaCollection.java
的类,把代码段输入进行测试 - p266 SimpleLinkedList.java: Java版链表实现
- 对比《数据结构》课上的C语言版
- 这个程序能编译通过吗?
- p268 WordCount.java: Set
- C语言中怎么分隔字符串?
- p269 Student.java: 怎么算重复
- equals与hashCode
- p270 Student2.java: 带equals和hashCode
- 这个代码值得好好研究学习
- p272 RequestQueue.java: 测试Queue的使用
- LinkedList可以看成Queue吗?
- 注意匿名类的使用
- p273 Stack.java: 用ArrayQueue实现栈
- p275 ArrayList.java: 泛型版的ArrayList
- 注意泛型语法
- p272 RequestQueue2.java: Lambda表达式的使用
- p283 ForEach.java: 利用iterable实现foreach
- p284 Sort.java: 使用Collection.sort对整数排序
- p285 Sort2.java: 自定义类型的排序,有问题
- p285 Sort3.java: 自定义类型的排序,实现Comparable接口
- 排序是升序还是降序?
- 修改代码,实现反序
- p287 Sort4.java: String默认实现升序
- p288 Sort5.java: 使用Comparator 实现对String的降序排序
- Collection.sort的重载方法
- Sort4.java,Sort5.java说明Java中对象排序,要么对象实现了Comparable可以直接sort,要么提供Comparator对象告知sort如何排序对String的降序排序
- 修改代码,使用Lambda表达式实现
- p290 Sort6.java: 优先排null
- import statci
- nullsFist
- reverseOrder
- p291 Messages.java: 使用HashMap
- p292 Messages2.java: 使用TreeMap排序
- p292 Messages3.java: 使用TreeMap反序排序
- p293 LoadProperties.java: 如何操作配置文件
- person.properties文件应该放在什么位置?
- p294 LoadSystemPros.java
- java -D
- p295 MapKeyValue.java: keySet访问键,values访问值
- 教材上说使用HashMap时结无序,为什么我的运行结果如下?下面的结果有序吗?
显示键 one two three 显示值 一 二 三
- 修改代码,使用TreeMap试试结果,有序吗?
- 代码中的forEach都是在什么类中定义的?
- p296 MapKeyValue2.java: entrySet,泛型
p297 MapKeyValue3.java: 使用Lambda表达式
课后练习
- 选择题
- 实现题
相关链接
- Map便利的默认方法
拓展
- 参考程序设计实践(The Practice of Programming) 第二章
返回目录
第十章 输入与输出
- 文件的读写
- 网络上传数据的基础
同样要先掌握父类中方法,核心类如下:
10.1 InputStream与OutputStream
- 流(Stream)是对「输入输出」的抽象,注意「输入输出」是相对程序而言的
- InputStream与OutputStream
- read
- write
- 二进制文件
- read
- 标准输入输出
- System.in: 标准输入,默认关联到键盘(终端输入)
- System.out: 标准输出,默认关联到显示器(终端输出)
- System.err: 标准错误,默认关联到显示器(终端输出)
- 输入输出重定向:setIn,setOut,setErr
- FileInputStream与FileOutPutStream
- 文件读写
- 装饰器类
- Decorator模式
- BufferedInputStream与BufferedOutputStream: 内部提供缓冲,提高效率
- DataInputStream与DataOutputStream:基本数据类型与字节的转换,API好好研究一下
- ObjectInputStream与ObjectOutputStream
- java.io.Serializable接口
10.2 字符处理类
- Reader与Writer
- 文本文件
- read
- write
- 字符处理装饰器
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaIO.java
的类,把代码段输入进行测试 - p305, IO.java: InputStrea/OutputStream的使用
- 注意多态的应用
- try with source:IO中几乎都必须处理异常
- 代码中的
-1
怎么来的?有什么用? - 读出的数据不够1024字节怎么处理?真正读出的字节数存在哪?
- 注意多态的应用
- p306 Copy.java: IO.java的测试类
- IO.dump中传入的参数与dump的声明一致吗?为什么可以这样传参数?
- 自己建一个id.txt的文件,里面输入自己的学号
- 把id.txt拷贝到id1.txt中
- 在命令行和IDE中都尝试一下
- p307 Download.java: IO.java的测试类
- IO.dump中传入的参数与dump的声明一致吗?为什么可以这样传参数?
- 把学院主页保存在besti.txt
- 在命令行和IDE中都尝试一下
- p309 StandardIn.java: 标准输出重定向
- 如何运行这个程序,把输入重定向到IO.java?
- p309 StandardOut.java:
- 如何运行这个程序把输出重定向到hw.txt中?
- p312 BufferedIO.java
- 缓冲功能
- p313 Member.java
- DataInputStream/ DataOutputStream的使用
- 补充gettter/setter代码
- 运行并修改p314 MemberDemo.java,加入自己几个好朋友
- writeUTF可以换成其他方法吗?
- p315 Member2.java
- ObjectInputStream/ ObjectOutputStream的使用
- 补充gettter/setter代码
- 运行并修改p316 Member2Demo.java,加入自己几个好朋友
- 测试一下实现不实现Serializable接口有什么不同?
- p317 CharUtil.java: 字符版本的IO.java
- 编译p318 CharUtilDemo.java 并运行测试
- java -Dfile.encoding=UTF-8
- -D 还可以指定什么
- 除了file.encoding file还可以指定什么?
- file.encoding除了UTF-8,还可以指定什么?
- p319 CharUtil2.java: 装饰器的使用
- 修改p318 CharUtilDemo.java 并运行测试 CharUtil2.java
课后练习
- 选择题
- 实现题
相关链接
- 乱码
拓展
- Java IO流学习总结
返回目录
第十一章 线程与并行API
Java语言内置多线程
11.1 线程
- 线程
- Thread与Runnable
线程生命周期
- 线程控制的一些方法
- interrupt
- sleep
- join
- stop(Deprecated)
- resume(Deprecated)
- suspend(Deprecated)
- destroy(Deprecated)
- 线程的停止、暂停、重启要程序员设定实现条件或使用并发API,不要调用Deprecated的方法
- 同步:synchronized与volatile
- 方法上
- 代码段上
- wait、notify、notifyAll
- ThreadGroup
- setMaxPriority
- enumerate
- activeCount
11.2 并行API
- Lock
- ReadWriteLock
- Condition
- Executor
- ScheduledThreadPoolExecutor
- ForkJoinPool
- 并发Collection
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaThread.java
的类,把代码段输入进行测试 - p325 TortoiseHareRace.java: 单线程版龟兔赛跑
- flags数组有什么作用?C语言中需要这么处理吗?
- 多运行几次,看看程序运行结果一样吗?
- p326 Tortoise.java Hare.java TortoiseHareRace2.java: 多线程版的龟兔赛跑
- 研究一下Runable接口的API
- 注意线程的生成方式,为什么可以这么做?
- 代码运行中发现了什么问题?
- TortoiseHareRace2运行时共有几个线程?
- 如果有Linux或Windows下多线程程序设计经验,与Java多线程对比一下有什么不同。比如:
- Linux中,主线程结束了,进程也结束了,程序就退出了,Java中是这样的吗?
- p330 DaemonDemo.java: Daemon线程
- 注释掉thread.setDaemon(true);,对比一下运行结果
- 注意产生线程默认是setDaemon(false)的
- P331 Download.java和Download2.java: 单线程和多线程的下载
- 对比一下这两个程序的效率
- Linux下 time java Download就可以得到程序运行时间,Windows下怎么办?(参考简易的windows下命令行统计程序运行时间程序)
p333 InterruptedDemo.java: interrupt唤醒线程
- p334 JionDemo.java: join
- 修改代码,对比测试join的功能
- p337 ThreadGroupDemo.java:
- 调用了Thread哪个构造方法?
- 理解Lambda表达式
- 调用了Thread哪个构造方法?
- p338 ThreadGroupDemo2.java: 处理线程没捕捉的异常
- Exception:异常, 台湾翻译成「例外」
- 理解运行结果
- p339 ArrayListDemo.java
- 修改代码达到线程安全
- p343 DeadLockDemo.java: 死锁
- 多运行几次,看看能不能出现死锁
- 如何修改代码保证没有死锁?
- p350 p351 Producer.java Consumer.java Clerk.java ProducerConsumerDemo.java: 生产者消费者
- 理解这个代码对以后学习《操作系统》有帮助
- p354 ArrayList.java: 线程安全的ArrayList
- Lock的使用方法
- 测试是不是线程安全
- p355 NoDeadLockDemo.java: tryLock
- 理解如何避免死锁的
- p357 ArrayList2.java: ReadWriteLock
- p359 ArrayList3.java: StampedLock
- p361 Clerk.java: Condition
- 用完整的生产者消费者代码测试
- 生产者消费者共用一个Condition对象
- p363 Clerk2.java
- 用完整的生产者消费者代码测试
- 生产者消费者各有一个Condition对象
- p364、p365、p366 Pages.java DirecExecutor.java Download.java:
- 并发API版 Download
p366 p367 ThreadPerTaskExecutor.java Download2.java:
p368 Download3.java: ThreadPoolExecutor
p369 FuterCallableDemo.java: Future,Callable
- p370 FuterCallableDemo.java: Future,Callable
- 使用ExecutorService
p371 SheduledExecutorServiceDemo.java: SheduledExecutor
p374 FibonacciForkJoin.java: ForkJoinPool
- P376 p377 Producer3.java Consumer3.java: 并发Collection的应用
- 编译运行
课后练习
- 选择题
- 实现题
相关链接
- Dealing with InterruptedException
- 正确使用 Volatile 变量
- StampedLock Idioms
- 费氏数列
返回目录
第十二章 Lambda
12.1 认识Lambda语法
- Lambda 教材的引入循序渐近、深入浅出
- Lambda去重复,回忆DRY原则
- Lambda表达式可读性更好
- Arrays.sort
- Comparator: 对比C语言中使用函数指针
- 匿名类与多态
- 方法引用(Method Reference)
- 新语法
- 一条语句用Lambda表达式,多条语句用方法引用
- 函数接口(Functional Interface)
- 就是只有一个抽象方法的接口
- Runnable
- Callable
- Comparator
- ...
- @FunctionalInterface
- 可引用的包括类的静态方法、成员方法、构造方法
- 就是只有一个抽象方法的接口
- 接口默认方法(Default Method)
- 不能使用类的成员变量
12.2 Functional与Stream API
- 使用Optional代替null
- 标准API的函数接口
- Consumer:一个参数,无返回值
- Function:一个参数,有返回值
- Predicate:一个参数,有返回值,返回值必须是boolean类型的
- Supplier:无参数,有返回值
- Stream与管道
12.3 Lambda与并行处理
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaLambda.java
的类,把代码段输入进行测试 - p384 LambdaDemo.java: Lambda
- 注意理解例子中的Lambda表达式怎么一步步从匿名类推出来的
- 体会Lambda表达式「去重复」、「易读」的好处
- 修改代码,实现逆序排序
- p384 p385 StringOrder.java StringOrderDemo.java: 方法引用
- 注意新语法
- 对比C++中的命令空间
- P389 ThisDemo.java: 再理解this
- 自己先猜一下运行结果
- p389 ThisDemo2.java: Lambda版
- 与ThisDemo对比
- p393 MethodReferenceDemo.java: 方法引用
- Function接口
- 理解map方法
- 构造方法的方法引用
- 如何运行这个程序?运行结果?
- p398 CustomerDemo.java: 默认方法
- 加几个一下main中的Customer的对象,让firstName,lastName,zipCode都有相同的和不同的
- 运行代码
- p407 PlayerDemo.java: Stream API
- 研究一下Stream类
- p409 EmplyeeDemo.java:
- 用Stream API 计算sum/average/max/min
- p411 EmplyeeDemo.java: reduce
P421 Async.java: CompletableFuture
课后练习
- 选择题:无
- 实现题
相关链接
- Java Lambda Tutorial
- Monadic Java
- Java 8: Definitive guide to CompletableFuture
返回目录
第十三章 时间与日期
13.1 认识时间与日期
- 时间的度量
- GMT(Greenwich Mean Time)时间:现在不是标准时间
- 世界时(Universal Time,UT):1972年UTC出来之前,UT等价于GMT
- 国际原子时(TAI):秒的定义
- 世界协调时间(Corrdinated Universal Time, UTC): 闰秒
- Unix时间: 1970.1.1 00:00:00开始的秒数
- epoch: java.util.Date epoch毫秒数
- 日历
- 儒略历(Julian Calendar)
- 格里高利历(Gregorian Calendar)
- ISO8601 标准
13.2 认识Date与Calendar
- 时区
- Date与DateFormat
- Date只用来获取epoch毫秒数
- DateFormat来格式化成人类理解的年月日时分秒
- Calendar: 时间的运算
- getInstance(): GregorianCalendar
- getTime()
- get()
- add()
- roll()
- after()
- before()
...
13.3 JDK8新时间日期API
- 机器时间 Instant
- 人类时间(ISO8601 标准)
- LocalDateTime
- LocalDate
- LocalTime
- ZonedDateTime
- OffsetdateTime
- Year
- YearMonth
- Month
- MonthDay
- TemporalAmount
- TemporalUnit
- TemporalAccessor
- Chronology
动手:
- 编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaTime.java
的类,把代码段输入进行测试 - p429 DateDemo.java: Date类测试
- 研究Date类会发现大多方法都Deprecated了,掌握这个例子就够了
- System.currentTimeMillis()的结果与这个例子有联系吗?测试一下
- p430 DateFormatDemo.java: DateFormat类
- 研究一下DateFormat类
- 发现代码中有什么问题了吗?
- p432 SimpleDateFormatDemo.java: 用SimpleDateFormat自定义日期格式
- 如何运行这个程序?
- 发现什么问题没有?
- p432 HowOld.java: 用SimpleDateFormat自定义日期格式
- 如何运行这个程序?
- 如何计算一个程序的运行时间?下面的方法行吗?测试一下。还有其他方法吗?
- Date begin = new Date();
- ...Java Code...
- Date end = new Date();
- long duration = end.getTime() - begin.getTime();
- p435 CalendarUtil.java: Calendar测试
- 为什么调用clone()?
- 研究Calendar类
- 研究GregorianCalendar类
- 修改一下代码,计算一下自己的岁数和活了多少天,结果准确吗?为什么?
- p436 TimeZoneDemo.java TimeZoneDemo2.java: TimeZone的测试
- 研究TimeZone类
- 修改代码获取和设置大陆的时区信息
- p439 ZonedDateTimeDemo.java: new Time API测试
- 研究LocalTime类
- 研究LocalDate类
- 研究ZonedDateTime类
- 研究OffsetdateTime类
- p440 MothDemo.java: DateCalendar测试
- 研究Year/Month等类
- 注意getValue()和oridinal的区别
- p442 HowOld2.java:
- 如何运行这个程序?
- 如何计算一个程序的运行时间?
- LocalDate
- Period
课后练习
- 选择题:无
- 实现题
相关链接
- Timezone Updater
- 写一手流畅的API
- Standard Calendar
返回目录
第十四章 NIO与NIO2
- NIO(New IO)-from JDK1.4
- NIO2 -from Java SE 7
14.1 认识NIO
- Channel: 衔接数据节点(与IO中的流对比)
- isOpen
- close
- ReadableByteChannel
- read
- WritableByteChannel
- write
- Buffer: 块操作
- clear
- flip
- rewind
- mark
- reset
- remaining
14.2 NIO2文件系统
- java。nio.file
- FileSystems
- Paths
- Files
- java.nio.file.atribute
- java.nio.file.spi
- FileSystemProvider
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaNIO.java
的类,把代码段输入进行测试 - p451 NIOUtil.java: Channel
- 研究Channel类及相关子类
- index.html存在哪了?打开看看内容对不对
- p455 PathDemo.java:
- 研究Path类
- 测试一下P455/p456的其他代码段
- p457 BasicFileAttributesDemo.java
- Linux下 stat 命令可以查看文件属性
- 文件属性和操作系统中的i-node什么关系?
- 文件属性和文件内容相关类分别是什么?
- 测试一下P457/p458的其他相关的代码段
- p458 Disk.java
- 研究DecimalFormat类
- 研究FileStore类
- p460 Download.java
- 程序如何运行?
P461 Roots.java: 找根目录
- p462 Dir.java: 遍历子目录
- 程序如何运行?
- p464 ConsoleFileVisitor.java:
- 研究FileVisitor类
p465 DirAll.java
- p467 LS.java: 过滤文件
- 程序如何运行?
- p468 LS2.java: 使用正则表达式过滤
- 程序如何运行?
课后练习
- 选择题:无
- 实现题
相关链接
- Legacy File I/O Code
- POSIX File Permissions
- Watching a Directory for Changes
拓展
- Java NIO
返回目录
第十五章 通用API
15.1 通用API
- 日志: 日志对信息安全意义重大,审计、取证、入侵检测等都会用到日志信息
- 日志API
- Logger: 注意无法使用构造方法生成Logger对象
- Logger logger = Logger.getLogger("xxx");
- getLevel
- setLevel
- Logger logger = Logger.getLogger("xxx");
- Level
- Handler:输出介质
- MemoryHandler
- StreamHandler
- ConsoleHandler: SimpleFormatter
- FileHandler:XMLFormatter
- SocketHandler
- Formatter: 格式化
- Filter: 过滤
- Logger: 注意无法使用构造方法生成Logger对象
15.2 国际化基础
Localization 本地化;Internationalization(i18n)国际化
- ResourceBundle
Locale
15.3 正则表达式
- 正则表达式简介
- 字符与元字符
- 字符类
- 贪婪、非贪婪、独占量词
- 边界比较
- 锚点
- 分组与反向引用
Pattern/Matcher
15.4 JDK8 API增强功能
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaAPI.java
的类,把代码段输入进行测试 - p471 LoggerDemo.java: 测试Logger
- Java API会用默认值,参考「积极主动敲代码,使用Junit学习Java程序设计」
- 研究 Logger 类
- p474 LoggerDemo2.java: 测试Level
- 研究Level类
- 修改代码,用setLevel同时改变Logger和Handler的Level,体会一下输出的不同
- 理解Logger/Level/Handler的关系
- 把Logger/Handler设置成不一样的Level,体会一下输出的不同
- p475 HandlerDemo.java: 日志存文件中
- 研究一下Handler类
- config.log在你计算机的什么位置。%h 从哪来的?还有什么其他模式字符串?
- 修改一下显示级别,看看config.log的内容有什么变化
- 学了下一章,想想日志能不能存数据库中?
- p477 Formatter.java: 自定义Formatter
- 覆盖format
- p481 Hello.java: I18N
- message.properties 放什么位置?
- 研究ResourceBundle类
- 运行程序
- 不修改代码如何显示“你好!世界!
- 如何进行中英文切换?
- p483 SplitDemo.java
- 修改代码,字符串改成csv,怎么分隔?
- 这个程序的功能用C语言怎么实现?
- p488 ReplaceDemo.java:
- 理解贪婪模式,非贪婪模式,独占模式
- p489 SplitDemo2.java: 部分匹配
- p489 SplitDemo3.java: 整词匹配
- 熟悉其他锚点
- p491 PatternMatcherDemo.java
- 研究Pattern类
- 研究Matcher类
- out.printf("%s find ", pattern.pattern())的作用?
- p492 Regex.java:
- 可以用这个代码学习测试教材中的正则表达式的相关内容
课后练习
- 选择题
- 实现题
相关链接
- ISO-639
- ISO-3166
- Quantifiers
- Lesson: Regular Expressions
拓展
- 「日志」参考程序开发与信息安全工具箱中的Log4J
- 「正则表达式」参考正则表达式入门
返回目录
第十六章 整合数据库
MySQL建议安装XAMPP,参考「程序开发与信息安全工具箱」。如果下载的是Portable版的,解压后注意先运行一下setup_xampp.bat,使用软件时读读readme 会解决不少问题。
16.1 JDBC入门
- JDBC(Java DataBase Connectivity)
- 驱动的四种类型
- JDBC-ODBC Bridge Driver
- Native API Driver
- JDBC-Net Driver
- Native Protocal Driver
- 服务提供者框架(Service Provider Framework):多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来
- 组件
- 服务接口(Service Interface)
- 提供者注册API(Provider Registration API)
- 服务访问API(Service Access API)
- 服务提供者接口
+JDBC API
- 服务接口(Service Interface): Connection
- 提供者注册API(Provider Registration API):DriverManager.registerDriver
- 服务访问API(Service Access API):DriverManager.getConnection
- 服务提供者接口:Driver - 组件
- 连接数据库
- 注册Driver: DriverManager.registerDriver()
- 获取Connection: Connection conn = DriverManager.getConnection(jdbcUrl, userName, password);
- 关闭Connection:
16.2 JDBC进阶
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
不少都是代码段,自己新建一个
TestJavaDB.java
的类,把代码段输入进行测试- p509 ConnectionDemo.java: 数据库连接测试,注意数据库用户名,口令要根据自己的实际情况修改
使用XAMPP中的PHPAdmin 建好数据库并进行测试
建数据库:
CREATE SCHEMA demo;
- 建数据库表
use demo;
CREATE TABLE t_message (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name CHAR(20) NOT NULL,
email CHAR(40),
msg TEXT NOT NULL
) CHARSET=UTF8;
+ [下载](http://dev.mysql.com/downloads/connector/j/)并在IDEA中配置驱动
- p511
课后练习
- 选择题
实现题
相关链接
MySQL JDBC Driver
拓展
- 21分钟 MySQL 入门教程
- 深入浅出SQL (Head First SQL,官网)
返回目录
第十七章 反射与类加载器
17.1 运用反射
17.2 了解加载器
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
不少都是代码段,自己新建一个
TestJavaBasic.java
的类,把代码段输入进行测试课后练习
- 选择题
实现题
相关链接
返回目录
第十八章 自定义泛型、枚举与注释
18.1 自定义泛型
18.2 自定义枚举
18.3 关于注解
动手:
编辑输入、编译、运行相关代码,并思考相关问题,会调试就更好了(参考「遇到问题为什么应该自己动手」)
- 不少都是代码段,自己新建一个
TestJavaGeneric.java
的类,把代码段输入进行测试 - p570 Sort.java P571 SortDemo.java: 类型边界定义
课后练习
- 选择题
实现题
相关链接
- 返回目录
补充:网络编程
1.
返回目录
补充:Java与安全
返回目录
补充:Android开发基础
返回目录
术语对照
英文 | 大陆 | 教材 |
---|---|---|
Access | 访问 | 存取 |
Annotation | 注解 | 标注 |
Back Refererence | 反向引用 | 回头参考 |
Class | 类 | 类别 |
Class File | 类文件 | 位码文档 |
Collection | 集合 | 收集 |
Dead Lock | 死锁 | 死结 |
Comment | 注释 | 批注 |
Config | 配置 | 组态 |
Default | 默认 | 预设 |
Exception | 异常 | 例外 |
File | 文件 | 文档 |
Flag | 标记 | 旗标 |
implement | 实现 | 操作 |
Interface | 接口 | 界面 |
Level | 级别 | 层级 |
Method Signature | 方法签名 | 方法签署 |
Method Reference | 方法引用 | 方法参考 |
Overflow | 溢出 | 溢值 |
Override | 覆盖 | 重新定义 |
Parameter | 参数 | 自变量 |
Priority | 优先级 | 优先权 |
Race Condition | 竞态条件 | 竞速情况 |
Round-Robin | 轮询 | 输流执行 |
Row | 行 | 列(错误?) |
Reference | 引用 | 参考 |
Regular Expression | 正则表达式 | 规则表示式 |
Scheduler | 调度程序 | 排班器 |
Source Code | 源码 | 原始码 |
Statement | 语句 | 描述 |
Stream | 流 | 串流 |
返回目录
参考资料
- Java学习笔记(第8版)
- 程序设计实践(The Practice of Programming)
- 代码大全(Code Complete)
欢迎关注“rocedu”微信公众号(手机上长按二维码)
做中教,做中学,实践中共同进步!
原文地址:http://www.cnblogs.com/rocedu/p/5182332.html
推荐网站:博客园、新浪微博、扇贝背单词、DKY背单词小组、有道云笔记、豆瓣读书
版权声明:自由转载-非商用-非衍生-保持署名| Creative Commons BY-NC-ND 3.0
如果你觉得本文对你有帮助,请点一下左下角的“好文要顶”和“收藏该文”