读后笔记 -- Java核心技术(第10版 卷I )Chapter1-3 Java 程序设计
本书源码:https://horstmann.com/corejava/
Java 8 API 文档:https://docs.oracle.com/javase/8/docs/api/index.html
Chapter1. Java程序设计概述
1.2 Java“白皮书”的关键术语
11个关键术语:
- 1)简单性:去除了C++的头文件、指针运算(甚至指针语法)、结构、联合、操作符重载、虚基类等;
- 2)面向对象:Java 将重点放在数据(对象)和对象的接口上。Java与C++的主要不同点在多重继承,在Java中,使用的是更简单的接口概念;
- 3)分布式:Java 有一个丰富的例程库,用于处理像 HTTP 和 FTP之类的 TCP/IP 协议。Java 能简便地通过 URL 来访问网络对象;
- 4)健壮性:Java 和 C++ 最大的不同在于 Java 采用的指针模型可以消除重写内存和损坏数据的可能性;
- 5)安全性:Java 适用于 网络/分布式 环境。为此耗费大量精力构建了比较安全可靠的系统;
- 6)体系结构中立:Java 编译器通过生成与特定的计算机体系机构无关的字节码指令;“JVM”;
- 7)可移植性:(1)Java规定了数据类型的固定大小,故比C++可移植性好;(2)为系统组成部分的类库,定义了可移植性的接口;
- 8)解释性: Java 解释器可以在任何移植了解释器的机器上执行 Java 字节码;
- 9)高性能: Java 即时编译器 JIT。参见另外一篇文章 https://www.cnblogs.com/bruce-he/p/15699282.html
- 10)多线程性:多线程带来更好的交互响应和实时行为;
- 11)动态性:Java 比 C/C++ 更具动态性;
1.3 Java applet 与 Internet
Java applet:可在网页中运行的 Java 程序。
Chapter 2. Java 程序设计环境
2.1 安装 Java 开发工具包
2.1.1 下载 JDK
| Java 术语 | ||
| 术语名 | 缩写 | 解释 |
| Java Development Kit | JDK | 编写 Java 程序的程序员使用的软件 |
| Java Runtime Environment | JRE | 运行 Java 程序的用户使用的软件 |
| Server JRE | --- | 在服务器上运行 Java 程序的软件 |
| Standard Edition | SE | 用于桌面或简单服务器应用的 Java 平台 |
| Enterprise Edition | EE | 用于复杂服务器应用的 Java 平台 |
| Micro Edition | ME | 用于手机和其他小型设备的 Java 平台 |
| Java FX | --- | 用于图形化用户界面的一个替代工具包,在 Oracle 的 Java SE 发布版本中提供 |
| OpenJDK | --- | Java SE 的一个免费开源实现,不包含浏览器集成或 Java FX |
| Java 2 | J2 | 过时的术语,用于描述1998年 ~ 2006年间的 Java 版本 |
| Software Development Kit | SDK | 过时的术语,用于描述1998年 ~ 2006年间的 JDK |
| Update | u | Oracel 的术语,表示 bug 修正的版本 |
| NetBeans | --- | Oracle 的集成开发环境 |
下载:1)JDK用于开发,而不是JRE;2)Windows(选择 x32/x64)或 Linux(选择 .tar.gz 版本)
2.2 设置 JDK
1)环境变量设置
1)windows(路径中最好不要有空格)-> 环境变量: JAVA_HOME:c:\Java\jdk_9.0.1 PATH:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin 2)Linux -> /etc/profile: export JAVA_HOME=/home/data/tools/jdk export JRE_HOME=$JAVA_HOME/jre export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
2)文档:(没找到文档下载,只找到一个在线版本) https://docs.oracle.com/javase/8/docs/api/index.html
2.3 命令行运行
> cd corejava\v1ch02\Welcome > javac Welcome.java > java Welcome #!注意,这个地方是类的名称,不能写成 Welcome.class,否则会出现 “不到或无法加载主类”
2.4 使用集成工具
下图使用 IJ,
后面一直 Next 到 Finish。
Chapter 3. Java 的基本程序设计结构
1. Java 语言规范: https://docs.oracle.com/javase/specs/
3.2. 注释
- // : 单行注释
- /* + */ : 一段行的注释
- /** + */ : 可自动生成文档
3.3 数据类型
| Java 数据类型 | ||
| 整型 |
int : 4字节 -2 147 483 648 ~ 2 147 483 647 (正好超过 20 亿) short: 2字节 -32 768 ~ 32 767 long: 8字节 -9 223 372 036 854 775 B08 ~ 9 223 372 036 854 775 807 byte: 1字节 -128 ~ 127 |
L/l: 长整型 0x/0X: 十六进制 0b/0B: 二进制 1_000_000: 数字加下划线,表示100万 * 八进制不建议用,数字前加0,容易混淆 |
| 浮点类型 |
float: 4字节 大约 ± 3.402 823 47E+38F (有效位数为 6 ~ 7 位) double: 8字节 大约 ± 1.797 693 134 862 315 70E+308 (有效位数为 15 位> |
F/f: float类型 D/d/: double类型(也是默认类型) 1)Double.POSITIVE_INFINITY, Double_NEGATIVE_INFINITY 和 Double.NaN 是是三个特殊的值, 实际很少遇到,可使用: if(Double.isNaN(x)) // check whether x is "not a number" 2)System.out.println(2.0-1.1) 将打印 0.8999999999999999,是因为浮点数值采用二进制系统表示 导致的舍入误差。如计算中不允许有任何舍入误差,应使用 BigDecimal 类 |
| char 类型 |
char 类型的字面量值要用''括起来,如 'A' 可表示为十六进制,其范围从 \u0000 ~ \Uffff |
特殊字符的转义序列: \b \u0008 \t \u0009 \n \u000a \r \u000d \'' \u0022 \' \u0027 \\ \u005c |
| boolean 类型 | true, false |
整数值和布尔值之间不能相互转换, 如 if (x=0) // oops... menat x ==0,在c++可以编译运行,其结果总是false,而java不能通过编译 |
3.4 变量
1. 变量
声明后,必须显式初始化。Java的声明尽可能靠近第一次使用的地方。Java 不区分变量的声明与定义【C/C++区分定义和声明: int i = 10; //定义 extern int i; //声明 】;
2. 常量
final:变量只能被赋值一次;常量名使用全大写。
static final:类常量,定义位于 main 方法的外部
public:一个常量被声明为 public,其他类的方法也可以使用这个常量
public class Constants2 { public static final double CM_PER_INCH = 2.54; // final 常量,static final 类常量--被一个类中的多个方法使用 public static void main(String[] args) { double paperWidth = 8.5; double paperHeight = 11; System.out.println("Paper size in centimeters:" + paperWidth * CM_PER_INCH + " by " + paperHeight * CM_PER_INCH) ; } }
3.5 运算符
1. 整数 除以 0,将会异常;浮点数 除以 0,将 无穷大 或 NaN。
2. 类型转换,实线:数据无损;虚线:有可能精度损失
3. 强制类型转换
double x = 9.997; int nx = (int) x; // 强制转换,nx = 9 int nx = (int) Math.round(x); // 对浮点进行舍入运算, nx =10。因为 round 返回的是 long 类型,所以需要 (int) 显式强转
4. 自增/减
int m = 7; int n = 7; int a = 2 * ++m; // now a is 16, m is 8 int b = 2 * n++; // now b is 14, n is 8 ** 不建议在表达式中使用 ++/--
| 优先级 | 运算符分类 | 结合顺序 | 运算符 |
| 分隔符 | 左结合 | . [] (方法调用 ) ; , | |
| 一元运算符 | 右结合 | ! ++ -- - ~ | |
|
算术运算符 移位运算符 |
左结合 | * / % + - << >> >>> | |
| 关系运算符 | 左结合 | < > <= >= instanceof(Java 特有) = = != | |
| 逻辑运算符 | 左结合 | ! && || ~ & | ^ | |
| 三目运算符 | 右结合 | 布尔表达式?表达式1:表达式2 | |
| 赋值运算符 | 右结合 | = *= /= %= += -= <<= >>= >>>= &= *= |= |
3.6 字符串
- substring:子串;
- +:拼接;
- .join():使用定界符拼接字符串;
- equals() / equalsIgnoreCase:检测两个字符串是否相等(区分/不区分大小写)。
- !不要使用“==”判断两个字符串是否相等,该运算符仅判断是否放在同一位置上。实际上,仅字符串常量是共享的,而 + 或 substring 等操作产生的结果并不共享。
- "" :空串; null:null 串 // 1)空串: if (str.length() == 0) 或 if (str.equals("")) 2)null 串: if (str == null)
3.7 输入输出
Scanner in = new Scanner(System.in); String name = in.nextLine(); // 接受字符串 int age = in.nextInt(); // 接受数值
| printf的转换符,如:Systen.out.printf("%,.2f", 10000.0 / 3.0); |
||||||
| 转换符 | 类型 | 举例 | 转换符 | 类型 | 举例 | |
| d | 十进制整数 | 159 | s | 字符串 | Hello | |
| x | 十六进制整数 | 9f | c | 字符 | H | |
| o | 八进制整数 | 237 | b | 布尔 | True | |
| f | 定点浮点数 | 15.9 | h | 散列码 | 42628b2 | |
| e | 指数浮点数 | 1.59e+01 | tx 或 Tx | 日 期 时 间 (T 强制大写) | 已经过时, 应当改为使用 javaJime 类,参见卷 II 第 6章 | |
| g | 通用浮点数 | 一 | % | 百分号 | % | |
| a | 十六进制浮点数 | 0xl.fccdp3 | n | 与平台有关的行分隔符 | 一 | |
| 用 于 printf 的 标 志,如: Systtem.out.prinf("%,(.2f", 100 / 3.0) | ||
| 标 志 | 目 的 | 举 例 |
| + | 打印正数和负数的符号 | +3333.33 |
| 空格 | 在正数之前添加空格 | | 3333.33| |
| 0 | 数字前面补 0 | 003333.33 |
| - | 左对齐 | 13333.33 | |
| ( | 将负数括在括号内 | ( 3333.33 ) |
| , | 添加分组分隔符 | 3,333.33 |
| # ( 对于 f 格式) | 包含小数点 | 3,333. |
| # (对于 x 或 0 格式) | 添加前缀 Ox 或 0 | Oxcafe |
| $ | 给定被格式化的参数索引。例如, %l $d,%l$x 将以十进制和 十六进制格式打印第 1 个参数 | 159 9F |
| < |
格式化前面说明的数值。 例如,%d%|
159 9F
|
|
1. 格式化:
1)参数格式化
// %1$:是对后面的第1个参数格式化, %2$:对第2个参数(new Date())的结果格式化 System.out.printf(Locale.ENGLISH, "%1$s %2$tB %2$te, %2$tY", "Due date: ", new Date()); Due date: December 21, 2021
2)格式说明符
2. 文件输入输出
// 读取文件 Scanner in = new Scanner(Paths.get("C:\\test.robot"), "utf-8"); // 写入文件 PrintWriter out = new PrintWriter("myfile.txt", "UTF-8");
3.8 控制流程
1. if (condition) statement
2. while (condition) statement / do statement while (condition);
3. for (int i = 1; i <= 10; i++)
- 1)for 循环第一部分(int i)/ 内部定义的变量,作用域仅for循环内
- 2)如要使用最终的值,需在for 循环外部定义。 int i; for (i = 1; i <= 10; i++)
- 3)不同的for循环可使用同一变量
4. switch
case 标签可以是:
- 类型是 char、bytte、short 或 int 的常量表达式
- 枚举常量
- 字符串字面量(Java SE 7 开始)
3.9 大数值
- BigInteger:实现任意精度的整数运算;
- BigDecimal:实现任意精度的浮点数运算
* 不能使用 +,* 计算,换成 add,multiply
3.10 数组
1. 声明: int[] a = new int[100];
- 数字数组,初始化值 0;
- boolean数组,初始化值 false;
- 对象数组(如字符串数组),初始化值 null;
2. for each 循环: for (variable : collection) statement
int[] a = new int[20]; for (int i = 0; i < 20; i++) { a[i] = i; } // 传统 for 循环打印 for (int i = 0; i < 20; i++) { System.out.println(a[i]); } // for each 打印 for (int num : a){ System.out.println(num); } // Arrays.toString 方式打印 System.out.println(Arrays.toString(a));
3. 数组初始化及匿名数组
// 初始化数组 int[] smallPrimes = {2, 3, 5, 7, 11, 13}; System.out.println(Arrays.toString(smallPrimes)); // new int[] {,,}:初始化一个匿名数组,然后赋值给另一个数组 smallPrimes = new int[] {17, 19, 23, 29, 31, 37}; System.out.println(Arrays.toString(smallPrimes)); //初始化一个长度为 0 的数组 new int[0]
4. 数组 copy 及排序 sort
// 两个变量引用同一个数组 int[] luckyNumbers = smallPrimes; luckyNumbers[5] = 12; // copy 数组, 第二个参数为长度, < 原数组长度:引用指定的数据; =:全复制; >:多余的补默认值 int[] copiedLuckyNumbers1 = Arrays.copyOf(luckyNumbers, luckyNumbers.length); int[] copiedLuckyNumbers2 = Arrays.copyOf(luckyNumbers, 2 * luckyNumbers.length); // 数组排序 Arrays.sort(luckyNumbers);
// 打印2维数组 for (double[] row : balance) { for (double b : row) { System.out.printf("%10.2f", b); } System.out.println(); }
5. 不规则数组
只能单独地创建行数组