bit与byte
- 计算机就是一系列的电路开关,每个开关会存在2种状态:off(关)和on(开) 如果电路是开的,则值为1;如果电路是关的,它的值是0 [这个部分会在计算机组成原理去更详细的解释]
- 一个0或者一个1存储为一个比特(bit),是计算机中最小的存储单位。二进制 0 和 1
- 计算机中基本的存储单元是字节(byte),每个字节由8个比特构成,比特是最基本的计算单位。所有的命令、代码、页面等等各种你在电脑上、手机上、终端上的操作都会转化为字节的运算。但是字节的计算本质是二进制比特的计算。
- 1Byte = 8bit
- 1KB = 1024 byte
- 1MG = 1024 kb
- 1GB = 1024 mg
-
内存
一个程序和它的数据在CPU中执行前必须移到计算机的内存中,也就是说,所有的计算操作都是在内存中进行的。那我们在之后的编码中,可以通过数据计算出执行此逻辑需要的内存,并且可以制造出某些JVM异常的原因。
- 每个字节都有唯一的地址。会用地址确定字节的位置,便于存储和获取数据。
- 如果想要加载数据,需要从硬盘 -> 内存 -> CPU
- 内存数据:断电消失
- 硬盘数据:持久保存
-
Java基础知识图解
最基础部分
Java的优势
简单性:简单的都是基本功,难以处理和理解的是业务。业务是有明确的上下文,深知业务可以更好的编排代码。所以,Java是简单的。并且Java的垃圾回收器已经比较完善了,有很多强大的功能。需要程序员手动去管理内存的很少了,且Java生态非常强悍和成熟。
- 可移植性:Java 先编译生成字节码,再由 JVM(Java 虚拟机)来解释执行,目的就是将统一的字节码转成操作系统可以识别的二进制码,然后执行。而针对不同的操作系统,都有相应版本的 JVM,所以 Java 就实现了可移植性。
- 安全性:Java适用于网络和分布式环境,Java可以构建防病毒、防篡改的应用程序。
- 运行时堆栈溢出,这是蠕虫病毒常用的攻击手段。
- 字节码验证,可以确保代码符合 JVM 规范并防止恶意代码破坏运行时环境。
- 安全的类加载,可以防止不受信任的代码干扰 Java 程序的运行。
- 全面的 API 支持广泛的加密服务,包括数字签名、消息摘要、(对称、非对称)密码、密钥生成器。
- 安全通信,支持 HTTPS、SSL,保护传输的数据完整性和隐私性。
- 并发性:多线程支持十分强悍。
对多个领域都有突出的表现:大数据、金融服务领域、物联网(IoT)领域、Web领域
Java跨平台的机制
Java跨平台的机制在于其将Java文件编译成所有Java虚拟机可以识别的class文件,类似在方法论中提到的去差异化设计。
- Java虚拟机是和平台有关的,因为不同操作系统存在不同的JDK,但是这些JDK都能保证识别所有的由其他JDK或者是自身JDK编译出来的class文件。这样一来,开源的JDK和非开源的JDK都要遵循一定的标准,要表达的意思就是,所有的”服务提供方“都要遵守”输出“的契约。这样才能够保证所有的class是完全通用的。
- 所有的class文件都需要运行在JDK之上,其JDK是跨平台的,可以理解为将Java代码的编译层和执行层进行了一次封装。
-
JDK和JRE和JVM
JDK:Java Development Kit 是Java开发工具包。其范围最大,包含JRE和JVM。其也会包含一些指令等,比如编译指令等。
- JRE:Java Runtime Environment 是Java运行时环境,包括 JRE 所有内容,以及开发应用程序所需的编译器和调试器等工具。JRE 提供了库、Java 虚拟机(JVM)和其他组件,用于运行 Java 编程语言、小程序、应用程序。如果你的机器上不需要将Java文件编译成class文件,那么只需要安装JRE即可,但是这种情况现在已经不存在,因为CI/CD工作流 自动化拉取代码、编译、执行、部署 需要,而且安装完整的JDK几乎没有成本。
- JVM:Java Virtual Machine 是Java虚拟机,整个Java的的核心,JVM可以理解为是一个虚拟出来的计算机,具备着计算机的基本运算方式,它主要负责把 Java 程序生成的字节码文件,解释成具体系统平台上的机器指令,让其在各个平台运行。

一些命令行
关键字,是Java中已经定义的,只能Java来使用。其中大部分已经使用,少部分没有使用,称为保留字。
- 所有的关键字如下 | Java关键字类别 | Java关键字 | 关键字含义 | | —- | —- | —- | | 访问控制 | private | 一种访问控制方式:私用模式,访问控制修饰符,可以应用于类、方法或字段(在类中声明的变量) | | 访问控制 | default | 一种访问控制方式:缺省模式,可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符 | | 访问控制 | protected | 一种访问控制方式:保护模式,可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符 | | 访问控制 | public | 一种访问控制方式:共用模式,可以应用于类、方法或字段(在类中声明的变量)的访问控制修饰符。 | | 类、方法和变量修饰符 | abstract | 表明类或者成员方法具有抽象属性,用于修改类或方法 | | 类、方法和变量修饰符 | class | 声明一个类,用来声明新的Java类 | | 类、方法和变量修饰符 | extends | 表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口 | | 类、方法和变量修饰符 | final | 用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 | | 类、方法和变量修饰符 | implements | 表明一个类实现了给定的接口 | | 类、方法和变量修饰符 | interface | 接口 | | 类、方法和变量修饰符 | native | 用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 | | 类、方法和变量修饰符 | new | 用来创建新实例对象 | | 类、方法和变量修饰符 | static | 表明具有静态属性 | | 类、方法和变量修饰符 | strictfp | 用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范 | | 类、方法和变量修饰符 | synchronized | 表明一段代码需要同步执行 | | 类、方法和变量修饰符 | transient | 声明不用序列化的成员域 | | 类、方法和变量修饰符 | volatile | 表明两个或者多个变量必须同步地发生变化 | | 程序控制 | break | 提前跳出一个块 | | 程序控制 | continue | 回到一个块的开始处 | | 程序控制 | return | 从成员方法中返回数据 | | 程序控制 | do | 用在do-while循环结构中 | | 程序控制 | while | 用在循环结构中 | | 程序控制 | if | 条件语句的引导词 | | 程序控制 | else | 用在条件语句中,表明当条件不成立时的分支 | | 程序控制 | for | 一种循环结构的引导词 | | 程序控制 | instanceof | 用来测试一个对象是否是指定类型的实例对象 | | 程序控制 | switch | 分支语句结构的引导词 | | 程序控制 | case | 用在switch语句之中,表示其中的一个分支 | | 程序控制 | default | 默认,例如:用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现 | | 错误处理 | try | 尝试一个可能抛出异常的程序块 | | 错误处理 | catch | 用在异常处理中,用来捕捉异常 | | 错误处理 | finally | 用在捕获异常的格式中,放在最后 | | 错误处理 | throw | 抛出一个异常 | | 错误处理 | throws | 声明在当前定义的成员方法中所有需要抛出的异常 | | 包相关 | import | 表明要访问指定的类或包 | | 包相关 | package | 包 | | 基本类型 | boolean | 基本数据类型之一,声明布尔类型的关键字 | | 基本类型 | byte | 基本数据类型之一,字节类型 | | 基本类型 | char | 基本数据类型之一,字符类型 | | 基本类型 | double | 基本数据类型之一,双精度浮点数类型 | | 基本类型 | float | 基本数据类型之一,单精度浮点数类型 | | 基本类型 | int | 基本数据类型之一,整数类型 | | 基本类型 | long | 基本数据类型之一,长整数类型 | | 基本类型 | short | 基本数据类型之一,短整数类型 | | 基本类型 | null | 空,表示无值,不能将null赋给原始类型(byte、short、int、long、char、float、double、boolean)变量 | | 基本类型 | true | 真,boolean变量的两个合法值中的一个 | | 基本类型 | false | 假,boolean变量的两个合法值之一 | | 变量引用 | super | 表明当前对象的父类型的引用或者父类型的构造方法 | | 变量引用 | this | 指向当前实例对象的引用,用于引用当前实例 | | 变量引用 | void | 声明当前成员方法没有返回值,void可以用作方法的返回类型,以指示该方法不返回值 | | 保留字 | goto | 保留关键字,没有具体含义 | | 保留字 | const | 保留关键字,没有具体含义,是一个类型修饰符,使用const声明的对象不能更新 |
数据类型
- Java中的数据类型可以分为2种,一种是基本数据类型,一种是引用数据类型。
- 基本数据类型是 Java 语言操作数据的基础,包括 boolean、char、byte、short、int、long、float 和 double,共 8 种。
- 引用数据类型,除了基本数据类型,其他的都是引用数据类型。这里使用《Java编程思想:第四版》的比喻:将对象引用比喻为遥控器,将其能够操控的电视机比喻为对象,那么使用遥控器可以操作电视机(对象引用操作对象实际的地址以及其数据)。

数据类型的大小 | 数据类型 | 默认值 | 大小 | | —- | —- | —- | | boolean | false | 1比特 | | char | ‘\u0000’ | 2字节 | | byte | 0 | 1字节 | | short | 0 | 2字节 | | int | 0 | 4字节 | | long | 0L | 8字节 | | float | 0.0f | 4字节 | | double | 0.0 | 8字节 |
char为啥是2个字节,这和JDK的编码有关。JDK内部使用UFT-16编码。(详细了解参见文末参考资料)
- 比较常见或者说是比较难以理解的问题是long的大小为8字节,float的大小为4字节。
- Java中long类型占8字节,1字节=8位(1byte=8bit)也就是64位,每一位都有0和1两种状态,64位也就可以表示2^64个状态,也就是2^64个数,而long类型是有符号的(分正负),负数用-2^63至-1表示,正数用0至2^63-1表示,加起来正是2^64个数。
- Java中float占4字节,但是其表达的数值范围大于long类型,这是为啥呢。
- 一个字节是8个二进制位,4个字节就是32个二进制位。
- 最左边的一位表示符号位。
- 最后面23位表示尾数(小数位,最大无限接近于1)
- 剩下的8位,为指数位:注意,是指数位置,是放在右上角的位置的。如2的4次方。二进制表示为 00000000~11111111 取值范围是0~255。
- 根据IEEE 754规定,其中0代表0,255代表无限大。去除这两个值,中间的范围是1~254。
- 且每个指数要减去127,所以范围是:-126~127 即最大为2^127。 远远大于long类型的最大值:2^63-1
- boolean:仅仅用来存储2个值:true或者false
- byte:byte的取值范围在 -128 ~ 127 之间。包含-128 和 127 默认值为0。比较特殊的就是 -128 的由来,规定 1000 0000 为 -128

- short:取值范围在 -32768 ~ 32767 之间。包含-32768 和 32767 默认值为0
- int:取值范围在 -2,147,483,648(-2^31)~ 2,147,483,647(2^31 - 1)之间 默认值为0
long:-9,223,372,036,854,775,808(-2^63) 和 9,223,372,036,854,775,807(2^63 -1)之间,包含最大值和最小值,默认值为 0。为了和int进行区分,当定义long类型的时候,必须使用大写的L作为末尾声明。禁止使用小写的l。
long startTime = 0L;long endTime = 100000L;
float:单精度的浮点数。遵循IEEE 754标准(二进制浮点数算术标准:参见文末参考资料链接),取值范围是无限的,默认值为 0.0f 这里float类型,强制带上小写的f。当然大写的F也可以,但是小写的已经足够了。数学计算严禁使用float进行计算,会有损失精度的问题。如需使用,使用BigDecimal进行计算,且必须使用 new BigDecimal(String str) 类型的构造函数。
- double:双精度的浮点数。遵循IEEE 754标准(二进制浮点数算术标准:参见文末参考资料链接) 数学计算严禁使用double进行计算,会有损失精度的问题。如需使用,使用BigDecimal进行计算,且必须使用 new BigDecimal(String str) 类型的构造函数。
- char:可以表示一个 16 位的 Unicode 字符,其值范围在 ‘\u0000’(0)和 ‘\uffff’(65,535)之间,使用 单引号包起来的 ‘’
- 引用数据类型:引用数据类型的默认值全部为null。
- 引用数据类型的引用,也就是上文提到的遥控器,其是放在栈中的,而被引用的对象,也就是电视机,其是放在堆中的。在Java执行的过程中,需要知道其需要执行的所有的数据的生命周期,其能够编译通过,则其class文件就可以在不被破坏的情况下,正确的被执行。代码块的执行,和代码的执行,我们在后面学习JVM的时候进行深入探讨。
引用数据类型的地址,可以通过toString方法来打印,如下
public class Object {// 略过其他方法public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}}
Java中所有的类都继承自Object类,如果子类没有重写toString方法,则会执行父类的toString方法。其实就是打印个哈希值地址。
这里会涉及到一个经常面试会问到的问题,为什么要重写equals和hashcode方法。这个地方我们讲到集合框架的时候会具体的进行分析。通过debug源码的方式进行分析。
String
String是一种特殊的引用类型。可以看一下他的源码
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {/** The value is used for character storage. */private final char value[];}
是有final修饰的,表示其是终类,不可被继承、不可被修改。
字符串比较复杂,其和JVM相关,会有这样的面试题:为什么String是final修饰的?后续我们看源码的时候,会解决一部分问题,在讲解JVM的时候,会解决剩下的问题。
运算符
运算符分类如下

- 算术运算符
算术运算符除了最常见的加减乘除,还有一个取余的运算符,用于得到除法运算后的余数,来串代码感受下。 ```java public class ArithmeticOperator { public static void main(String[] args) {
int a = 10;int b = 5;System.out.println(a + b);//15System.out.println(a - b);//5System.out.println(a * b);//50System.out.println(a / b);//2System.out.println(a % b);//0b = 3;System.out.println(a + b);//13System.out.println(a - b);//7System.out.println(a * b);//30System.out.println(a / b);//3System.out.println(a % b);//1
} }
- 加法(+)、减法(-)、乘法(*)很好理解,但除法(/)和取余(%)比较特殊。因为数字在程序中分为2种,浮点型和整型。如果都是整型,则不会出现浮点型,否则会出现。
```java
public class ArithmeticOperator {
public static void main(String[] args) {
int a = 10;
float c = 3.0f;
double d = 3.0;
System.out.println(a / c); // 3.3333333
System.out.println(a / d); // 3.3333333333333335
System.out.println(a % c); // 1.0
System.out.println(a % d); // 1.0
}
}
需要注意的是,当浮点数除以 0 的时候,结果为 Infinity 或者 NaN。
System.out.println(10.0 / 0.0); // Infinity System.out.println(0.0 / 0.0); // NaNInfinity 的中文意思是无穷大,NaN 的中文意思是这不是一个数字(Not a Number)
当整数除以 0 的时候(10 / 0),会抛出异常
Exception in thread "main" java.lang.ArithmeticException: / by zero at com.ldl.baselearn.model01.ArithmeticOperator1.main(ArithmeticOperator1.java:29)算术运算符中还有两种特殊的运算符,自增运算符(++)和自减运算符(—),它们也叫做一元运算符,只有一个操作数。 ```java public class UnaryOperator1 { public static void main(String[] args) {
int x = 10; System.out.println(x++);//10 (11) System.out.println(++x);//12 System.out.println(x--);//12 (11) System.out.println(--x);//10} }
- 一元运算符可以放在数字的前面或者后面,放在前面叫前自增(前自减),放在后面叫后自增(后自减)
- 前自增和后自增是有区别的,拿 int y = ++x 这个表达式来说(x = 10),它可以拆分为 x = x+1 = 11; y = x = 11,所以表达式的结果为 x = 11, y = 11。拿 int y = x++ 这个表达式来说(x = 10),它可以拆分为 y = x = 10; x = x+1 = 11,所以表达式的结果为 x = 11, y = 10
```java
int x = 10;
int y = ++x;
System.out.println(y + " " + x);// 11 11
x = 10;
y = x++;
System.out.println(y + " " + x);// 10 11
- 关系运算符

- 位运算符
在学习位运算符之前,需要先学习一下二进制,因为位运算符操作的不是整形数值(int、long、short、char、byte)本身,而是整形数值对应的二进制
public class BitOperator { public static void main(String[] args) { System.out.println(Integer.toBinaryString(60)); // 111100 System.out.println(Integer.toBinaryString(13)); // 1101 } }
```java
public class BitOperator1 {
public static void main(String[] args) {int a = 60, b = 13; System.out.println("a 的二进制:" + Integer.toBinaryString(a)); // 111100 System.out.println("b 的二进制:" + Integer.toBinaryString(b)); // 1101 int c = a & b; // 0011 1100 // 0000 1101 // 0000 1100 System.out.println("a & b:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = a | b; // 0011 1100 // 0000 1101 // 0011 1101 System.out.println("a | b:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = a ^ b; // 0011 1100 // 0000 1101 // 1100 1110 System.out.println("a ^ b:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = ~a; System.out.println("~a:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = a << 2; System.out.println("a << 2:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = a >> 2; System.out.println("a >> 2:" + c + ",二进制是:" + Integer.toBinaryString(c)); c = a >>> 2; System.out.println("a >>> 2:" + c + ",二进制是:" + Integer.toBinaryString(c));} }
- 按位左移运算符
```java
public class LeftShiftOperator {
public static void main(String[] args) {
System.out.println(10 << 2);//10*2^2=10*4=40
System.out.println(10 << 3);//10*2^3=10*8=80
System.out.println(20 << 2);//20*2^2=20*4=80
System.out.println(15 << 4);//15*2^4=15*16=240
}
}
// 10<<2 等于 10 乘以 2 的 2 次方;10<<3 等于 10 乘以 2 的 3 次方。
按位右移运算符
public class RightShiftOperator { public static void main(String[] args) { System.out.println(10 >> 2);//10/2^2=10/4=2 System.out.println(20 >> 2);//20/2^2=20/4=5 System.out.println(20 >> 3);//20/2^3=20/8=2 } } // 10>>2 等于 10 除以 2 的 2 次方;20>>2 等于 20 除以 2 的 2 次方。无符号右移动 ```java public class RightShiftOperator2 { public static void main(String[] args) {
int a = -4; // 1111 1111 1111 1111 1111 1111 1111 1100 System.out.println(Integer.toBinaryString(a)); int b = a >>> 2; // 0011 1111 1111 1111 1111 1111 1111 1111 System.out.println(Integer.toBinaryString(b));} }
- **逻辑运算符**
- 逻辑与运算符(&&):多个条件中只要有一个为 false 结果就为 false
- 逻辑或运算符(||):多个条件只要有一个为 true 结果就为 true
```java
public class LogicalOperator {
public static void main(String[] args) {
int a = 10;
int b = 5;
int c = 20;
System.out.println(a < b && a < c);//false && true = false
System.out.println(a > b || a < c);//true || true = true
}
}
- 逻辑非运算符(!):用来反转条件的结果,如果条件为 true,则逻辑非运算符将得到 false。
- 单逻辑与运算符(&):很少用,因为不管第一个条件为 true 还是 false,依然会检查第二个。
- 单逻辑或运算符(|):也会检查第二个条件。
也就是说,& 和 | 性能不如 && 和 ||,但用法一样: ```java public class LogicalOperator { public static void main(String[] args) {
int a = 10; int b = 5; int c = 20; System.out.println(a < b & a < c);//false && true = false System.out.println(a > b | a < c);//true || true = true} }
- 赋值运算符
```java
public class AssignmentOperator {
public static void main(String[] args) {
int a = 10;
int b = 20;
a += 4;//a=a+4 (a=10+4)
b -= 4;//b=b-4 (b=20-4)
System.out.println(a);
System.out.println(b);
}
}
- 不过在进行数值的赋值时,需要小点心,比如说下面这种情况:

- 因为整型默认都是int类型,但是这里是short类型,需要的类型范围变小,就会有问题
- 所以需要强转,可能存在精度丢失问题

- 除此之外,还会有边界问题,比如说,两个非常大的 int 相乘,结果可能就超出了 int 的范围
```java
public class BigIntMulti {
public static void main(String[] args) {
} }int a = Integer.MAX_VALUE; int b = 10000; int c = a * b; System.out.println(c); // -10000
- 程序输出的结果为 -10000,这个答案很明显不是我们想要的结果,虽然可以通过右侧表达式强转 long 的方法解决
```java
public class BigIntMulti2 {
public static void main(String[] args) {
int a = Integer.MAX_VALUE;
int b = 10000;
long c = (long) a * b;
System.out.println(c); // -10000
}
}
- 但尽量不要这样做,结果非常大的时候,尽量提前使用相应的类型进行赋值 ```java long a = Integer.MAX_VALUE - 1; long b = 10000; long c = a * b; System.out.println(c); // 21474836460000
- **三元运算符**
- 三元运算符用于替代 if-else,可以使用一行代码完成条件判断的要求。
```java
public class TernaryOperator {
public static void main(String[] args) {
int a = 2;
int b = 5;
int min = (a < b) ? a : b;
System.out.println(min);
}
}
// 如果 ? 前面的条件为 true,则结果为 : 前的值,否则为 : 后的值

- 这个比较简单,在下面进行演示即可,有些场景下,可能会积攒很多的if-else,维护起来是比较麻烦的,比如多一个case,就要多一层if。之后会使用策略模式进行去除if-else ```java // if语句 if(boolean 表达式 ){ // 为 true 就执行 }
// if-else语句 if(boolean 表达式 ){ // 为 true 就执行 }else{ // 为 false 就执行 }
// if-else-if int a = 1; if(a == 1){ // a == 1 就执行 }else if (a == 2){ // a == 2 就执行 }else if (a == 3){ // a == 3 就执行 }else { // a != 1 && a != 2 && a != 3 就执行 }
// if 嵌套语句 int a = 1; int b = 2; if(a == 1){ if(b == 2){
}
}
- **switch语句:**switch语句可以用来判断变量与多个值之间的相等性。变量的类型可以是 byte、short、int、long,或者对应的包装器类型 Byte、Short、Integer、Long,以及字符串和枚举。**至于switch为什么支持字符串String和枚举,会在String和枚举专门解释。**
```java
switch(变量) {
case 可选值1:
// 可选值1匹配后执行的代码;
break; // 该关键字是可选项
case 可选值2:
// 可选值2匹配后执行的代码;
break; // 该关键字是可选项
......
default: // 该关键字是可选项
// 所有可选值都不匹配后执行的代码
}
- 变量可以有 1 个或者 N 个值。
- 值类型必须和变量类型是一致的,并且值是确定的。
- 值必须是唯一的,不能重复,否则编译会出错。
- break 关键字是可选的,如果没有,则执行下一个 case,如果有,则跳出 switch 语句。
- default 关键字也是可选的。
- 关键字break:跳出循环或者switch
- 关键字continue:略过当前的执行条件
- 关键字return:结束当前方法,自然也就跳出循环了
```java
public class Switch1 {
public static void main(String[] args) {
} }int age = 20; switch (age) { case 20: System.out.println("上学"); break; case 24: System.out.println("苏州工作"); break; case 30: System.out.println("洛阳工作"); break; default: System.out.println("未知"); break; // 可省略 }
- **for循环**

- 普通的 for 循环可以分为 4 个部分
- 初始变量:循环开始执行时候的初始条件
- 条件:循环每次执行时要判断的条件,如果为 true,就执行循环体;如果为 false,就跳出循环。当然了,条件是可选的,如果没有条件,则会一直循环
- 循环体:循环语句需要执行的代码块,直到条件变为 false
- 自增/自减:初识变量变化的方式
```java
for(初识变量;条件;自增/自减){
// 循环体
}
for (int i = 0; i < 5; i++) {
System.out.println("hello LDL");
}
双层for循环
public class PyramidForExample { public static void main(String[] args) { for (int i = 0; i < 5; i++) { for (int j = 0; j <= i; j++) { System.out.print("❤"); } System.out.println(); } } }for-each:for-each 循环通常用于遍历数组和集合,它的使用规则比普通的 for 循环还要简单,不需要初始变量,不需要条件,不需要下标来自增或者自减 ```java for(元素类型 元素 : 数组或集合){
// 要执行的代码 }
// case public class ForEachExample { public static void main(String[] args) { String[] strings = { “111”, “2222” }; for (String s : strings) { System.out.println(s); } } }
- **无限 for 循环:**
```java
public class InfinitiveForExample {
public static void main(String[] args) {
for (;;) {
System.out.println("InfinitiveForExample.main");
}
}
}
- while循环
```java
while(条件){
//循环体
}
// case
public class WhileExample { public static void main(String[] args) { int i = 0; while (true) { System.out.println(“DDD”); i++; if (i == 5) { break; } } } }
// 无限for循环
while (true) { // 执行体 }
- **do-while循环**
```java
do{
// 循环体
}while(条件);
// 例子
public class DoWhileExample {
public static void main(String[] args) {
int i = 0;
do {
System.out.println("LDL");
i++;
if (i == 5) {
break;
}
} while (true);
}
}
// 无限循环
do {
System.out.println("DDD");
} while (true);
- 比较
数组
- 顾名思义:是一组固定类型的组合。
- 如何定义数组 ```java int[] anArray;
int[][] anArray;
int anArray[][];
// index 必须有值 二维数组 int anArray[][] = new int[index][];
// 初始化
String[] strings = { “111”, “2222” };
int[] anArray = new int[10]; // 大小10个,默认值是0 这个就是基本数据类型的默认值,其他数据类型的默认值和之前的讲的一致
// 访问数组 String[] strings = { “111”, “2222” }; // 数组长度为2,下标从0开始 strings[0] strings[1] strings[2] // 抛出下标越界异常 // 数组可以使用循环语句进行输出
- 数组的索引从0开始,那么为什么从0开始:当计算机拿到一个数组的时候,拿到的其实是数组的地址,也就是下标为0的地址,举个例子如下
```java
String[] strings = { "111", "2222","33333" };

有关数组相关的基本算法和操作,会在后面讲Arrays工具类和ArrayList源码时候,更多的去学习。
其他
有些方法会进行重写,比如equals、hashcode方法、toString方法。在什么时候进行重写,是有一定的条件的,当然也可以无条件进行重写,但是有时候没必要的哈。
- toString方法,当你想要知道这个数据内部是啥的时候,所有的对象的打印都是输出的toString方法。阿里巴巴开发手册要求所有的POJO类都必须重写toString方法。如果有继承。则必须使用super.toString()
equals、hashcode方法已经mark,在集合的部分进行讲解。
参考资料
-128的二进制补码怎么来的:https://zhidao.baidu.com/question/303175158130244284.html
- 为什么Java中的char类型只有两个字节:https://www.zhihu.com/question/483613181
- 解析IEEE 754 标准:https://www.cnblogs.com/HDK2016/p/10506083.html
- 沉默王二的博客:https://itwanger.gitee.io/tobebetterjavaer/#/
