读后笔记 -- 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. 不规则数组

只能单独地创建行数组