# gorge4j-study **Repository Path**: pifu/gorge4j-study ## Basic Information - **Project Name**: gorge4j-study - **Description**: Java 基础学习项目 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2019-10-18 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Java开发语言基础相关知识 说明:本文以分类列表的方式将 Java 开发语言基础相关的代码展示出来,方便检索和学习。 > 注:本文基于的硬件 / 软件环境 > 硬件:MacBook Pro > 操作系统:macOS Catalina 10.15 > IDE:Eclipse Version: 2019-03 (4.11.0) ## 目录 ## 代码使用说明 ### 第一步:创建目录 Windows 系统下 请在 D:\ 盘目录下创建 jstudy 目录,例如:`D:\jstudy`。在代码编写时,Windows 系统下的目录是这样的:`D:\\jstudy` 注意:Windows 下通过反斜杠 `\` 来表示目录的分割,在 Java 里使用两个反斜杠 `\\` 来表示 `\`,要特别注意。 macOS 系统下 请在所在用户目录下创建 jstudy 目录,例如:`/Users/guoyingxia/jstudy`。在代码编写时,macOS 系统下的目录是这样的:`/Users/guoyingxia/jstudy` ### 第二步:下载项目 将 gorge4j-study 项目下载到本地 IDE 的工作空间(workspace) ### 第三步:导入项目 在 IDE 中导入 gorge4j-study 项目 ### 第四步:运行项目 第一种方式: 在 IDE(Eclipse / IntelliJ IDEA) 中直接运行各演示示例 。 第二种方式: 命令行的运行方式 以 HelloWorld.java 为例,操作如下: // Windows 系统下 // 进入到源代码所在目录(以下 workspace-git 为工作空间目录) $ cd D:\workspace-git\gorge4j-study\src\com\gorge4j // 编译(此处的例子,Eclipse 的编译文件 class 生成目录为项目根目录下的 bin 目录,所以此处示例输出到 bin 目录,也可以指定到其它目录) javac -d D:\workspace-git\gorge4j-study\bin HelloWorld.java // 进入到 bin 目录 $ cd D:\workspace-git\gorge4j-study\bin // 运行 $ java com.gorge4j.HelloWorld // 运行结果: // Hello World! // macOS 系统下 // 进入到源代码所在目录(以下 guoyingxia 为用户目录,workspace-git 为工作空间目录) $ cd /Users/guoyingxia/workspace-git/gorge4j-study/src/com/gorge4j // 编译(此处的例子,Eclipse 的编译文件 class 生成目录为项目根目录下的 bin 目录,所以此处示例输出到 bin 目录,也可以指定到其它目录) javac -d /Users/guoyingxia/workspace-git/gorge4j-study/bin HelloWorld.java // 进入到 bin 目录 $ cd /Users/guoyingxia/workspace-git/gorge4j-study/bin // 运行 $ java com.gorge4j.HelloWorld // 运行结果: // Hello World! 第三种方式: 可以批量删掉程序中的 package 代码:`package com.gorge4j;` ,将所有程序拷贝到项目所在根目录 gorge4j-study,即不需要 com.gorge4j 目录了,然后通过命令行直接在项目目录下运行就可以了。 // 进入到项目所在目录 cd /.../gorge4j-study // 编译程序 javac HelloWorld.java // 运行程序 java HelloWorld 常识: 同一个文件里只能有一个 public 类,并且 public 类名须与文件名一致,main 方法只能写在 public 类里,这种设定可避免引用时造成混乱。 ## 以下是代码列表的明细
是否常用 分类 示例 备注
Java入门 HelloWorld.java 最简单的入门例子
Java语言的基本语法 -> 代码编写规则 CodeRegex.java 1、一条命令以分号 ";" 结束;
2、块(block)是指括在一对大括号里的部分;
3、Java 关键字间的多个空格视作一个。
Java语言的基本语法 -> 注释 Annotate.java Java 中注释有 3 种类型,详见代码
Java语言的基本语法 -> 标识符 Identifier.java 1、Java 里的标识符只能是大/小写字母、数字、美元符号、下划线及上述组合;
2、不能以数字开头;
3、不能为 Java 关键字;
4、最大长度为 65534 个字符。
Java语言的基本语法 -> 变量和常量 VariableAndConstant.java Java 中类名以大写字母开头,变量和方法名以小写字母开头,一般采用驼峰命名的规则。
虽然不是强制要求,但是强烈建议遵守规范。
Java语言的基本语法 -> 数据类型 Java 里的数据类型分为基本数据类型(Primitive Type)和对象数据类型(Object Type)
基本数据类型分为:
逻辑型(Logical,也称为布尔型,1个字节)
字符型(Textual)
整型(Integral)
--byte (1个字节)
--short (2个字节)
--int (4个字节)
--long (8个字节)
实数类型(Floating,也称为浮点数)
--float (4个字节)
--double (8个字节)
Java语言的基本语法 -> 数据类型 -> 基本数据类型 -> 逻辑型 Logical.java 逻辑型是表达真(true)假(false)的数据类型,在内存中占一个字节
Java语言的基本语法 -> 数据类型 -> 基本数据类型 -> 字符型 Textual.java
*AlphabetToUnicode.java
Java 使用字符型存储单个字符,占2个字节内存。
使用 Unicode 字符集处理文字,Unicode 使用 2 个字节表示一个字符,几乎可以处理所有国家的语言文字。
注意:Java 中,字符型属于基本数据类型,而字符串是对象数据类型。因此,像 char a = "A"; 是错误的,因为 "A" 不是字符类型,而是一个字符串对象(String 类型),char a = 'A'; 才是正确的赋值形式。
Java语言的基本语法 -> 数据类型 -> 基本数据类型 -> 整型 Integral1.java
Integral2.java
*To.java
*IntegerToBinary.java
byte (1个字节,-128~127)
short (2个字节,-32768~32767)
int (4个字节,-2147483648~2147483647)
long (8个字节,-9223372036854775808~9223372036854775807)
Java语言的基本语法 -> 数据类型 -> 基本数据类型 -> 实数型 Floating.java float (单精度类型,4个字节,-1.45E~3.4028235E+38)
double (双精度类型,8个字节,-4.9E-324~1.7976931348623157E+308)
Java语言的基本语法 -> 数据类型 -> 基本数据类型 -> 对象类型 StringType.java
Java语言的基本语法 -> 类型转换 -> 自动类型转换 AutoCasting.java 变量 变量 结果
byte byte -> int
byte short -> int
byte int -> int
short int -> int
int int -> int
int long -> long
long long -> long
byte float -> float
int float -> float
long float -> float
float double -> double
double double -> double
注意:float 型是比 long 型更大的数据类型,long 型数据占用 8 个字节的内存空间,float 型数据仅占用 4 个字节的内存空间。但是,由于 long 型无法展示小数(float 型变量则可以),所以我们将 float 型看作是比 long 型更大的数据类型。
Java语言的基本语法 -> 类型转换 -> 强制类型转换 Casting.java 注意:编写程序是要时刻留心数据类型的转换,机器的执行跟人的思维习惯某些时候存在差异。
Java语言的基本语法 -> 类型转换 -> String型与基本数据类型之间的运算 StringCasting.java String 对象与基本数据类型的数据可以进行 ”+” 运算,其结果值为一个 String 型的对象,即”字符串+整数(实数)=字符串”。
Java语言的基本语法 -> 运算符 元算符的优先级(由高到低):
单目运算符(!、~、+、-、++、--)—>算术运算符(+、-、*、/、%)—>位移运算符(<<、>>、>>>)—>关系元算符(>、<、>=、<=、==、!=)—>逻辑元算符(&&、||、&、|、^)—>三目运算符(?=)—>赋值运算符(=、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=)
速记口诀:单算位关逻三赋
注意:小括弧 () 的优先级最高
Java语言的基本语法 -> 运算符 -> 逻辑非 Operator1.java 逻辑非运算符 ! 是表示逻辑非的单目运算符,它把真(true)变为假(false),把假(false)变为真(true)
Java语言的基本语法 -> 运算符 -> 位非运算符 BitNot.java 位非运算符 ~ 是表示位非的单目运算符,它的运算规则是:逢1变0,逢0变1
Java语言的基本语法 -> 运算符 -> 符号运算符 Symbolic.java 符号运算符 +、- 分别用于表示正数和负数
Java语言的基本语法 -> 运算符 -> 增减运算符 Operator2.java
Operator3.java
Operator4.java
增减运算符 ++、-- 是使变量值增 1 或减 1 的单目运算符
Java语言的基本语法 -> 运算符 -> 算术运算符 Alone3_1.java 算术运算符指加 +、减 -、乘 *、除 /,还包括求余运算符 %
Java语言的基本语法 -> 运算符 -> 位移运算符 Operator5.java 位移运算符 <<、>>、>>> 用来移动比特位
Java语言的基本语法 -> 运算符 -> 关系运算符 Operator6.java 关系运算符 <、>、>=、<=、==、!= 用来比较两个操作数的大小/相等/不相等等关系,比较所得的结果值为 boolean 型,它经常也成为比较运算符,常用在条件语句中。
注意:
“=” 与 “==” 的不同点
“=” 是一个赋值运算符,a = b 表示将变量 b 的值赋值给变量 a。
“==” 是一个比较运算符, a == b 表示如果 a 与 b 相等,则返回 true,否则返回 false。
Java语言的基本语法 -> 运算符 -> 快速逻辑与和快速逻辑或 Operator7.java
Operator8.java
Operator9.java
&& 运算
A----B----A&&B
true true true
true false false
flase true false
false false false
|| 运算
A----B----A||B
true true true
true false true
false true true
false false false
快速逻辑与(&&)、快速逻辑或(||)称为短路运算符
A&&B:若 A 为 false,则整个表达式即为假,此时 B 将不会参与运算,因此将出现 false 概率最高的表达式放到前面是推荐的做法;
A||B:若 A 为 true,则整个表达式为真,此时 B 将不会参与运算,因此将出现 true 概率最高的表达式放到前面是推荐的做法。
Java语言的基本语法 -> 运算符 -> 位运算符:位与、位或、位异或 Operator10.java &:作位与运算
|:作位或运算
^:作位异或运算
例如:A & B 为比较两个操作数的对应比特位,若都为 1,则结果为 1,否则为 0
a -> 1110(表示十进制 14)
b -> 1100(表示十进制 12)
a & b -> 1100(表示十进制 12)
Java语言的基本语法 -> 运算符 -> 三目运算符 Operator11.java
Alone3_2.java
三目运算符格式:
条件式 ? 值1 : 值2
如果条件表达式为真,则表达式的值取值1,否则取值2
注意:三目运算符可以嵌套
Java语言的基本语法 -> 运算符 -> 赋值运算符 Operator12.java 运算符 = 就是赋值运算符。除 = 之外,还有 +=、-=、*=、/=、&=、^=、|= 等赋值运算符,一般将 = 运算符称为纯赋值运算符。
小常识:
以下三种方法都会使 a 的值增 1。
a++;
a+=1;
a=a+1;
以下三种方法都会使 a 的值减 1。
a--;
a-=1;
a=a-1;
Java语言的基本语法 -> 运算符 -> 对象运算符 对象运算符 instanceof 结果值为 boolean 型,A instanceof B:如果 A 是 B 的对象,则返回 true,否则,返回 false
程序流程控制语句 条件语句(if、switch) 针对某种条件进行某种处理
循环语句(for、while、do-while) 重复执行某一段代码
异常处理语句(try-catch-finally) 处理程序发生的异常
程序流程控制语句 -> if语句介绍 if 语句是条件语句的一种形式,它针对某种条件作出相应的处理
程序流程控制语句 -> if语句格式1 If1.java
程序流程控制语句 -> if语句格式2 If2.java
程序流程控制语句 -> if语句格式3、4 If3.java
If3_1.java
If4.java
Alone4_1.java
Alone4_2.java
Alone4_3.java
注意:多分支 if 语句,永远只执行其中一条或一条也不执行。建议把触发条件概率较高的条件放到更前面执行。
另外,Java 中 else if 语句中间是隔开的,但是在 JavaScript 脚本语言中, elseif 是连在一起的,这点需要留意一下。
另外,Java 使用 Unicode 字符集,所以 Java 程序中可以使用文字来作为变量的名称,例如可以使用汉字作为变量的名称使用。
程序流程控制语句 -> switch语句 Switch1.java
Switch2.java
Switch3.java
Switch4.java
switch 语句也是一种条件语句,它的语法格式如下:
switch(表达式) {
case 值1:命令1;
case 值2:命令2;
case 值3:命令3;
default: 命令n;
}
若(表达式==值1),则执行命令1、2、3、n。
若(表达式==值2),则执行命令2、3、n。
若(表达式==值3),则执行命令3、n。
加入表达式的值与值1、2、3、都不相符,则执行命令n。
注意:表达式的结果必须是整型数字(byte/Byte、short/Short、int/Integer)、字符(char/Character,本质上也是数字,字母或中文都是可以的)、枚举(Enum)等形式,JDK1.7 之后支持 String 类型。
break 语句在 switch 语句中,用于终止一种情形;在循环语句中,用于强制退出循环。
continue 语句为跳出本次循环,继续执行下一次循环,注意 break 与 continue 的差异。
程序流程控制语句 -> for语句 For1.java
For2.java
For3.java
For4.java
For5.java
For6.java
For7.java
For8.java
For8_2.java
Alone4_4.java
Alone4_5.java
Alone4_6.java
For9.java
For10.java
For11.java
For12.java
For13.java
For14.java
For15.java
For16.java
Alone4_7.java
Alone4_8.java
Alone4_9.java
*Diamond.java
*Diamond1.java
*Diamond2.java
*Diamond4.java
*MultiplicationTable1.java
*MultiplicationTable2.java
for 语句是一种循环语句,它在某种条件满足时,反复执行某些语句。for 循环语句可以嵌套,嵌套后就是多重循环语句
注意:
for 语句中,若条件表达式始终为真,则会出现死循环的情况。编程时,一定要考虑周全,防止程序陷入死循环中。
程序流程控制语句 -> while语句 While1.java
While2.java
类似 for 循环语句,while 也是循环语句,也可以进行嵌套。
程序流程控制语句 -> do-while语句 DoWhile1.java do-while 语句同 while 语句作用类似,但是它首先执行然后再判断条件表达式,与 while 循环语句的不同之处是 do-while 循环语句至少被执行一次。
类与对象 -> 类的定义与对象的创建 Class1.java 类是对象的模版,对象是类的实体/实例。对象封装了现实生活中客观实体的属性与行为/动作,把它的属性称为成员变量,把它的行为动作称为成员方法/函数。创建对象的一个行为/动作就是构造函数/方法。
类与对象 -> 引用赋值 Class2.java 将对象的名称称为引用(变量)。因为引用代表对象,所以也可以把引用称为对象。引用赋值就是给对象的名称赋值
类与对象 -> 成员方法 Class3.java
类与对象 -> 成员方法 -> void返回类型 Class4.java
Class5.java
void 本身就有“空的、什么都没有”的意思,所以它表示 main() 方法无任何返回值。
注意:只是表示方法不用 return 或者 return 具体类型的值,并不表示不能 return。
类与对象 -> 成员方法 -> 无参方法 Class6.java 无参方法是指形式参数为空,即没有形式参数的方法
类与对象 -> 成员方法 -> 多参方法 Class7.java
Alone5_1.java
Alone5_2.java
Alone5_3.java
多参方法是指有多个形式参数的方法,这多个形式参数之间使用逗号分隔
类与对象 -> 局部变量和成员变量 Class8.java
Class9.java
局部变量在方法内部声明,并且也只能在方法内部声明。局部变量在外层的方法被调用时被分配内存,并且在方法执行完毕后自动释放内存而消亡。方法中的形式参数是局部变量的一种。
类与对象 -> this引用 Class10.java
Class11.java
Alone5_4.java
this是一个引用对象自身的引用
类与对象 -> 静态变量与静态方法 Class12.java
Class13.java
静态成员变量在不创建类的对象的情况下,也可以使用,它是所有对象共有的变量。普通成员变量(non-static)只有在创建了类的对象后才能被使用。与此相反,静态变量可以不先创建对象而直接使用。
类与对象 -> 成员与静态方法的关系 Class14.java
Class15.java
通常情况下,只有在对象存在的条件下,才可以使用成员变量与成员方法。然而,静态方法则不需要首先创建对象,可以直接调用它。
类与对象 -> 包与导入 Class16.java
Class17.java
Class18.java
package 的字面含义为:“捆、束”。在 Java 中,包指接口和类的集合,或者说包是接口和类的容器。Java 语言提供了大量的类,这些类根据类型功能的不同,被分别放在不同的包中。Java 中的包与目录类似。
类与对象 -> 访问控制符 Class19.java
Class20.java
Class21.java
Java中的访问控制符(access modifier)种类如下:
出现在成员变量与成员方法之前的访问控制符
private(当前类访问权限,同一个类中)
public(公共访问权限,全局范围)
default(friendly)(包访问权限,同一个包中)
protected(子类访问权限,子类中)
出现在类之前的访问控制符
public
default(friendly)
类与对象 -> 重载 Class22.java
Class23.java
Class24.java
Alone5_5.java
重载(overload)是指在同一个类中定义多个同名但内容不同的成员方法
类与对象 -> 构造函数 Class25.java
Class26.java
Class27.java
Class28.java
Class29.java
Class30.java
Alone5_6.java
构造函数的名字与类名一致,它没有任何的返回值,并且其前也不允许有void关键字。把编译器为我们创建的无参构造函数称为缺省(default)构造函数。缺省的构造函数没有参数,也没有函数体,即它不做任何事情,其唯一的功能就是创建对象。我们可以在一个构造函数内调用其它被重载了的构造函数。实现这一目的的手段就是使用 this()。
类与对象 -> 类的初始化 Class31.java 我们不仅可以使用构造函数初始化成员变量,也可以用其它方法。比如在定义类的同时给成员变量赋值,创建改类的对象时,其成员变量就会被赋入指定的值。
类与对象 -> 静态块 Class32.java static{…} 静态块主要用来初始化静态变量及静态方法。
类与对象 -> 实例块 Class33.java 实例块在创建类的实例(即创建类的对象)时被执行。构造函数也是在创建类的对象时被执行,但两者相比,实例块要优先于构造函数执行。
注意:如果在程序中同时使用实例块和构造函数,就会使代码变得很复杂,因此,在程序中一般较少使用示例块,更常用的是构造函数。
数组 数组类别:
基本数据类型数组:
字符型数组:’A’,’D’,’q’,’b’,……
整形数组:123,456,-564,……
实数型数组:2.13,3.0,-1.23F,……
对象型数组:
String型数组:”abc”,new(“def”),”可心”,……
此外,还有不计其数的对象型数组
根据数组的维数分类,又可以将数组分为:一维数组、二维数组、三维数组,……
数组 -> 基本数据类型数组 Array1.java
Array2.java
Alone6_1.java
字符型数组:’A’,’D’,’q’,’b’,……
整形数组:123,456,-564,……
实数型数组:2.13,3.0,-1.23F,……
数组 -> 一维数组的初始化 Array3.java 与基本数据类型一样,也可以对数组进行初始化。例如:
int[] a=new int[]{1,2,3,4,5};
数组 -> 对象数组 Array4.java
Array5.java
Alone6_2.java
Array6.java
Array7.java
对象数组(object array)又叫引用型数组,对象数组实际上就是引用的集合。即,对象数组中的元素就是引用。
例如:String型数组:”abc”,new(“def”),”可心”,……
数组 -> 二维数组 Array8.java
Array9.java
Array10.Java
Array11.java
Alone6_3.java
*MagicSquareTest.java
二维数组是一维数组构成的数组。
小常识:
定义二维数组的方法。
int[][] a; // 建议的方式
int[] a[];
int a[][];
以上三种方法都可以用来定义二维数组,但是建议用第一种方式。
数组 -> 三维数组 Array12.java
Array13.java
三维数组是二维数组构成的数组。
对象与方法 -> 对象的创建与销毁 Object1.java
Object2.java
Object3.java
Object4.java
我们可以根据需要创建对象,另一方面,有时也需要销毁它们。对象销毁是指对象释放内存,从内存中消除。只有准确地掌握了对象的创建与销毁的时机,才能灵活地使用对象。否则,我们无法随心所欲地进行程序设计。所以,准确地掌握了对象的创建与销毁的时机是十分重要的。
finalize() 方法是所有 Java 对象都拥有的方法,垃圾收集器在回收对象时会自动调用对象的 finalize() 方法来释放系统资源。
对象与方法 -> 值传递调用 Object5.java
Object6.java
在方法调用时,若其形式参数的数据类型为基本数据类型,那么,请使用值传递调用。
对象与方法 -> 引用传递调用 Object7.java
Object8.java
Object9.java
Object10.java
引用传递调用(pass by reference)指调用一个形式参数为引用变量的方法。
注意:字符串对象所引用的字符串不会被改变。
String s = new String("abcdef");
无法将 s 所引用的字符串 “abcdef” 变为其它字符串。原因在于,String 类的成员方法中并不存在用来改变字符串的方法。
对象与方法 -> 获取命令行参数 Object11.java
Alone7_1.java
如果要设计一个Copy.class类,用以实现将文件abc.txt复制到A:\abc.txt文件中。程序执行时,应该使用下面命令。
java Copy abc.txt A:\abc.txt
所以,程序应该要接收这两个参数(abc.txt与abc.txt),并将文件保存下来。main()方法中的形式参数String[] args正有此功能。args是一个字符串型的一维数组。
args[0] = "abc.txt"
args[1] = "A:\abx.txt"
详见 Object11.java 示例
对象与方法 -> 返回对象引用 Object12.java
Object13.java
正如可以将引用传递给形式参数一样,也可以将对象引用返回。
对象与方法 -> 返回新对象 Object14.java 在方法中,可以创建新的对象,并将其返回。
对象与方法 -> 自引用 Self1.java
SinglyList1.java
看下面的 Person 类。此类中包含一个 Person 型的成员变量 friend,它实际上是一个引用变量,可以引用自类型的对象。我们称此为自引用(selt-reference)。
class Person{
String name;
Person friend; // 自类型引用
}
对象与方法 -> 递归调用 Recursion1.java
Alone7_2.java
Recursion2.java
所谓递归调用就是指方法调用自身的现象。
继承 -> 继承的概念 Inher1.java Java 继承的概念:子类拥有父类的成员
继承 -> 子类对象的创建 Inher2.java 在创建子类对象时,系统会先调用父类构造函数初始化继承自父类的成员,随后,调用子类构造函数初始化子类成员。 系统之所以自动地调用父类的构造函数,是因为子类构造函数的最上端隐含着 “super();”
继承 -> this与super Inher3.java
Alone8_1.java
this与this()用来引用自身对象自身的成员,而super与super()则用来引用那些继承自父类的成员。
this:一个引用自身对象的引用
this():本身的构造函数
super:一个用来引用继承而来的成员的引用
super():父类的构造函数
构造函数的特征:
构造函数是创建对象时被调用执行的函数,它仅被调用执行一次,执行完毕后,对象即被创建出来。
构造函数没有返回值,其前面也不需要添加任何说明其返回值类型的关键字。
在构造函数中也可以使用 this(...) 来调用其它构造函数。
继承 -> 继承中的访问控制符 Inher4.java 继承自父类的成员的访问控制符会影响到子类。根据父类成员的访问控制符的不同,子类中有的父类成员可以被访问,有的则无法访问。
继承 -> 覆盖 Inher5.java
Inher6.java
Inher7.java
我们把子类拥有与父类相同成员的情况成为覆盖(override)。
成员变量的覆盖:变量名相同
成员方法的覆盖:返回值类型、方法名、形式参数都相同
访问控制符可以使用与父类相同或比父类权限更大的控制符。
正确:private —> public,default —> public
错误:public —> private,public —> default
覆盖父类成员的目的在于通过在子类中重新定义扩展父类的功能。
继承 -> 多态 Inher8.java
Alone8_2.java
在 Java 中,多态指的是拥有相同的形式,但根据不同的情形拥有不同的机能的特性。实现了重载或覆盖的方法拥有相同的名字,但不同情形下,它们又拥有不同的功能,所以重载与覆盖实际上是一种多态。
继承 -> 引用的范围 Inher9.java 引用变量可以引用子类的对象。父类型引用变量的引用范围:继承自父类的成员 + 被覆盖的成员。
继承 -> 引用变量的类型转换 Inher10.java 向父类型引用变量赋值子类型引用变量,是允许的。但是,相反,向子类型引用变量指派父类型引用变量,则不被允许。
继承 -> Object类 HashCodeTest.java Java 中的所有类(包括使用者自定义的类)都自动继承 Object 类。即 Object 类是所有类的父类。所以,Java 的所有对象都拥有 Object 类的成员。
继承 -> “==”与equals() Inher11.java “==” 运算符一般用于基本数据类型的比较中。如果对两个引用对象作比较,两个引用对象引用同一个对象时,返回 true,否则返回 false。
Object 类的 equals() 方法使用 “==” 运算符比较两个对象,这是两者的相同之处。String 类重载了继承自 Object 类的 equals() 方法,所以 String 类对象在进行 equals() 方法时是不同的,需要留意这个差异。
注意:使用equals()时的注意事项
未重载 equals() 方法的类的对象使用该方法与另以对象进行比较时,则返回 false,即使这两个对象拥有相同的内容。这是因为那个未重载 equals()方法的类实际上是调用了 Object 类的 equals() 方法。
继承 -> Object型引用变量 Inher12.java
Inher13.java
Alone8_3.java
Object 类是所有类的父类,所以 Object 型引用变量可以用来引用所有的对象。
继承 -> 类的层级图 Inher14.java 我们将类的层级图想象为类的族谱,所有类的始祖是 Object 类,Object 类是所有类的祖先,所以它位于层级图的最顶层。
抽象类与接口 -> 抽象类 Abstract1.java 包含抽象方法的类称为抽象类(abstract class)。在定义抽象类时,要在 class 前加上 abstract 关键字。
注意:继承了抽象类的子类一定要覆盖所继承的抽象方法,否则,子类也会变成抽象类。
abstract 方法不能为 private 或 static 所修饰
abstract 方法是子类应覆盖的方法,所以在抽象类中申明它时,不要使用 private 关键字(private 意味着抽象类的外部无法访问,既然无法访问,覆盖也就无从谈起);
static 方法在不创建对象时也可以被调用,所以其方法体(body)应该被定义。若无方法体,也就不能以“类.方法名()”的形式对其调用,所以abstract方法(无方法体)不能被 static 关键字修饰。
抽象类与接口 -> final关键字 Final1.java
*FinalTest2.java
final 关键字含义为:最后、最终、终端。final 关键字可以用来修饰变量、方法和类。
final 关键字含义为:最后、最终、终端。final 关键字可以用来修饰变量、方法和类。
public final int a = 10;
如上,若在变量前加了 final 关键字,则表明 a 为常量(constant)。即首次给变量 a 赋予某个值后,以后便不能再给它赋其它值。
final 关键字也可以出现在方法前面,如下所示:
public final void f(){…}
我们将此类方法称为最终方法。继承含括最终方法类的子类不能覆盖该最终方法。若子类可以改变最终方法,从而改变其功能,将会导致致命性错误的出现,最终方法用以保护方法的功能,禁止对方法的功能做出任何修改。
在类之前使用 final 关键字,意味着其他类无法继承该类。我们已经知道 System 类与 String 类。如果 Ststem 类可以被继承,它的子类改变了它的功能,这将会给系统带来致命性错误。String 类与其他类有千丝万缕的联系,若对其进行继承并改变其功能,将会给其他类带来巨大乃至不可修复的错误。所以它被定义成了 final 类。
抽象类与接口 -> 接口 Interface1.java
Interface2.java
Interface3.java
Interface4.java
Interface5.java
*Interface6.java
interface 字面含义为界面,它是两个对象相互作用的接口。我们经常提及的 API(Application Program Interface)就是一系列接口,因为应用程序与运行体制正是通过API进行相互通信的。所以,我们可以将接口看作两个对象相互通信的规则或约束。声明抽象方法的原因就在于定义一种子类可以覆盖进而使用它的约束。
Java 接口中,所有方法都是抽象的,所有变量也都是 static 常量,接口本身就是一种约束。
接口的所有方法都是抽象方法,所以实现此接口的类只有全部覆盖了接口的全部抽象方法,才能创建对象。注意:这里我们把继承接口称为实现接口,使用的是 implements 关键字,而不是 extends 关键字。与抽象类相比,接口更具有抽象性,实现接口的类必须实现接口中所有抽象方法。与继承的概念类似,实现也意味着实现接口的类会继承接口的所有成员。
注意:static 和 default 关键字用在接口中 JDK 1.8 之后才支持,示例见 Interface6,规则如下
如果一个类中实现了两个接口,这两个接口中有相同签名的抽象方法,在类中只需要重写一次这个方法;
如果一个类中实现了两个接口,这两个接口中有相同名字不同参数列表的抽象方法,在类中只需要分别重写两个方法;
如果接口中有 default 修饰的方法,可以选择重写或者不重写;
如果两个接口里的方法签名相同都是 default 方法,在类中需要重写该方法;
如果两个接口签名相同的方法,一个接口是抽象方法,另一个是 default 修饰有方法体。这是该类也必须重写该方法;
方法签名的含义:方法名和形参列表共同组成方法的签名。
抽象类与接口 -> Cloneable接口 Cloneable1.java 有时我们需要复制对象,并将对象的副本传递给方法。我们把复制对象的过程称为克隆。
Java 在产生对象副本时,遵从以下约定。
某对象若想产生自身的副本:
1. 创建该对象的类必须实现 Cloneable 接口。
2. 创建该对象的类必须覆盖 Object 类的 clone() 方法。
clone() 方法会返回对象的副本。
抽象类与接口 -> Enumeration接口 Enumeration1.java 实现了 Enumeration 接口的对象内部持有给定的元素(element),需要时,可将它们顺次取出来。
内部类 Java 中,内部类有 4 种,它们分别为:静态类(static class)、成员类(member class)、局部类(local class)、匿名类(anonymous class)
静态类 作为类的静态成员而存乎于某个类的内部
成员类 作为类的成员而存乎于某个类的内部
局部类 存乎于某个方法内部的类
匿名类 存乎于某个类的内部,但无名称的类
内部类 -> 静态类 Static1.java static 和 dynamic 的字典释义分别为:“静态的”和“动态的”,两者的含义刚好相反。static 变量一旦被分配内存,将直到程序执行完毕,才会释放内存,从内存中消失。但是,普通成员变量(non-static)随着对象的创建而产生,并随着对象的消亡而消失,即普通变量是动态的。
内部类 -> 成员类 Member1.java
Member2.java
Member3.java
作为类的成员而存乎于某个类的内部的类
内部类 -> 局部类 Local1.java
Local2.java
局部类与局部变量一样是指在方法内部定义的类。
内部类 -> 匿名类 Anony1.java
Anony2.java
匿名类是为唯一对象而定义的类。
异常处理 Excep1.java 在进行程序设计和运行程序过程中,发生错误是不可避免的。对此,Java 提供了富有弹性的解决之道,可以保证程序在发生错误时仍能顺序执行下去,而不是中断程序。但是,Java 并非能捕获所有错误,我们把 Java 能够捕获的错误称为异常(exception)。
异常处理 -> try-catch语句 Excep2.java
Excep3.java
Excep4.java
Alone11_1.java
Java 的异常处理时通过 try-catch 语句实现的。使用 try-catch 语句,可以保证程序在发生异常时继续执行下去,而不是终止退出。
异常处理 -> Exception种类 Excep5.java 在 Java 类库的每个包中都定义了异常类,所有这些类都是 Throwable 类的子类。Throwable 类属于 java.lang 包,每个 Java 程序运行时系统都会自动引入此包,故无需再使用 import 语句导入它。Throwable 类派生有两个子类,分别为:Exception 类和 Error 类。
异常处理 -> 可抛出异常的方法 Excep6.java
Excep7.java
Excep8.java
Excep9.java
Excep10.java
Alone11_2.java
当我们调用某个方法时,可能会发生异常,我们把这种方法叫做可抛出异常的方法。可抛出异常的方法并不总是抛出异常,它是指可能抛出异常的方法。
小常识:
RuntimeException异常
此类异常即使不对其进行捕获处理,编译仍能顺利通过,但在运行时会被系统抛出。
异常处理 -> 自定义异常 Excep11.java 用户可自行定义异常类,只需继承 Exception 类即可。
常用API之一 -> java.lang.String String1.java
String2.java
StringCompare.java
String3.java
String4.java
String5.java
Alone12_1.java
字符串是字符系列的集合,也可将其视作字符的数组。Java 语言使用 String 类对其进行表达。String 类将字符串存储于 char 型数组中,并将其进行有效的管理。
常用API之一 -> java.lang.StringBuffer String6.java
String7.java
Alone12_2.java
StringBuffer 类提供了 String 类不支持的添加、插入、修改、删除之类的操作。总之,您若想对字符串进行操作,可以用 StringBuffer 类。缓冲区(buffer)指存储字符串的内存,即字符数组(char[])。对字符串的任何添加或删除操作都会引起缓冲区长度的改变。
常用API之一 -> wrapper class Wrapper1.java
Wrapper2.java
Alone12_3.java
wrapper类指将基本数据类型包装成相应类型对象的类。
wrapper类 说明
Boolean 将boolean型数据包装成Boolean类对象
Byte 将byte型数据包装成Byte类对象
Character 将char型数据包装成Character类对象
Short 将short型数据包装成Short类对象
Integer 将integer型数据包装成Integer类对象
Long 将long型数据包装成Long类对象
Float 将float型数据包装成Float类对象
Double 讲double型数据包装成Double类对象
常用API之一 -> java.lang.Math Math1.java
Math2.java
Math3.java
Alone12_4.java
java 的 java.lang.Math 类提供了大量的方法,用于支持各种数学运算及其他有关运算。这些方法都为静态(static)方法,故无需创建此类对象,直接用类名做前缀引用它即可。
常用API之一 -> java.lang.Math.BigInteger BigInteger1.java BigInteger 类用来表示大整数。此处所谓的“大整数“是指基本数据类型(int、long)无法存储的整数。
常用API之一 -> java.lang.Math.BigDecimal BigDecimal1.java BigInteger 类用来处理大整数,而 BigDecimal 类则用来处理大的10进制数。并且 BigDecimal 类也提供了实数运算。
Java输入与输出 -> File类 File1.java
File2.java
File3.java
Alone13_1.java
File 类提供与文件或目录相关的信息。在详细介绍此类之前,我们首先要弄明白何为路径(path)? 所谓路径(path)就是指文件的路径,它既可以是文件,也可以是目录。
字符 “\” 与其它字符相结合,会产生某种特殊的功能。在这里,我们使用双斜线来表示一个反斜线(若不使用双反斜线,就会发生错误)。Windows 系统下目录的分割使用 “\”,所以在 Java 代码中在 Windwos 系统下运行时需要使用 “\\” 来代表目录的分割符 “\”,这点需要特别注意。
“\n” 由两个字符组成,但仍被视为单个字符。‘\n’ 会将光标移到下一行行首,即具有换行的功能。我们把这种由反斜线开头,后面跟上转义字符,再由单引号括起来的字符序列,称为转义字符(escape字符)。
小常识
escape字符
\n →换行
\t →水平制表
\\ →反斜线
\" →双引号
Java输入与输出 -> 流 -> InputStream和OutputStream stream 对象大体分为两大类:一类负责输入(input),一类负责输出(output)。这些类的最终父类分别为:InputStream 和 OutputStream 类。
Java输入与输出 -> 流 -> FileInputStream和FileOutputStream File4.java
File5.java
File6.java
File7.java
这两个类负责文件的读写操作。FileInputStream 类继承自 InputStream 类,提供从文件读取数据的功能。FileOutputStream 类继承自 OutputStream 类,用于向文件写入字节数据。
Java输入与输出 -> 流 -> FilterStream File8.java InputStream 类与 Outputstream 类皆以 byte 为单位读写数据,很难处理诸如:char, int, double, String 型的数据。然而,倘若使用了 filter stream 类,则能非常方便地处理它们。filter stream 流分为 FilterInputStream 和 FilterOutputStream 两个流类。
Java输入与输出 -> 流 -> FilterStream -> DataInputStream和DataOutputStream File9.java
File10.java
Alone13_2.java
Alone13_3.java
DataInputStream 与 DataOutputStream 类分别继承自 FilterInputStream 与 FilterOutputStream 类,并且,它们风别实现了 DataInput 接口与 DataOutput 接口。
Java输入与输出 -> 流 -> 字符流 前面学过的流都是以 byte 为单位处理数据,我们将之称之为字节流(byte stream)。倘若用这种流处理字符(2个字节),则需要更多繁琐的操作,为解决此类问题,Java 语言引入了字符流(character streams)。character streams 以字符为单位进行输入输出,它又可以分为 Reader 类与 Writer 类。Reader 类负责字符输入工作,而 Writer 类则负责字符输出。
Java输入与输出 -> 流 -> 字符流 -> InputStreamReader和OutputStreamWriter File11.java
Java输入与输出 -> 流 -> 字符流 -> BufferedReader与BufferedWriter File12.java
File13.java
BufferedReader 类与 BufferedWriter 类分别继承自 Reader 类与 Writer 类。这两类由于内部用了缓冲(buffer)机制,所以它们可以以行为单位进行输入输出。
Java输入与输出 -> 流 -> 字符流 -> FileReader与FileWriter File14.java FileReader 类与 FileWriter 类分别继承自 InputStreamReader 与 OutputStreamReader 类,提供了将字符写入文件或从文件读出的简便方法。
Java输入与输出 -> 流 -> 字符流 -> 从System.in获取数据 Keyboard1.java
Keyboard2.java
Keyboard3.java
Alone13_4.java
java.lang.System 类的 in 属性声明如下:
public final static InputStream in = new InputStream();
in 对应于系统的标准输入,用于从标准输入设备(键盘)读入数据。
Java输入与输出 -> 流 -> 字符流 -> PrintStream与PrintWriter PWriter1.java PrintStream 类与 PrintWriter 类都是打印输出流,它们在许多方面提供了相似的功能。它们可以将各种基本数据类型的数据输出至字符串流中,并且提供自动刷新(flush)功能。并且,由于它们内部已经对异常做了处理,所以使用它们时不会发生异常。倘若你想知道异常是否发生,只需调用 checkError() 方法即可。这两个流的不同点存在于自动刷新(flush)功能的设定上,PrintStream 会在调用 println() 方法或输出已含换行符('\n')的字符串时自动刷新(flush),但是,PrintWriter 仅在调用 println() 方法时自动刷新(flush)。
事实上,一直在使用 PrintStream,只是自己未察觉而已。刚开始学习 Java 时,使用的 System.out 即为 PrintStream 对象。
Java输入与输出 -> 流 -> RandomAccessFile RAF1.java
RAF2.java
RAF3.java
RandomAccessFile 类是随机文件访问类,支持对文件的随机读写操作。随机访问文件是指可以读写其存储的任意位置数据的文件。我们可以将其内存储的数据看做一字节数组。在随机访问文件中存在一个文件指针(file pointer),通过移动文件的指针可以实现对数据的任意读写的操作
Java输入与输出 -> 流 -> 对象系列化 stream 可以很容易地将由连续的比特构成的基本数据类型的数据传送至流中。但是倘若想将数据的集合(对象)写入流中,则应将构成对象的数据排列成一系列的数据,再将其写入流中。我们将这个过程称为对象的系列化(serialization)。反之,将系列化的数据恢复为原来对象的过程称之为系列化的解体(deserialization)。简而言之,对象的系列化指将对象写入流,而系列化解体则指从流中获取数据,重构对象的过程。
Java 的对象可分为可系列化对象与不可系列化对象两种。例如,可系列化对象有 String,StringBuffer,Frame,Applet 等。在 API 文档中查看这些类,您就会发现这些类都实现了 Serializable 接口。即,可系列化的类实现了 Serializable 接口。反之,不可系列化的类则未实现 Serializable 接口。
事实上,Serializable 接口无任何抽象方法,它仅用于表明类是可系列化的,我们将这样的接口称为标识接口。
Java输入与输出 -> 流 -> 对象系列化 -> ObjectInput与ObjectOutput ObjectInput 与 ObjectOutput 接口分别继承了 DataInput 和 DataOutput 接口,提供了用于读写基本数据类型和对象数据类型的方法。
ObjectInput 提供了 readObject() 方法,此方法用于将对象从流中读出。ObjectOutput 提供了 writeObject() 方法,此方法用于将对象写入流中。
Java输入与输出 -> 流 -> 对象系列化 -> ObjectOutputStream Serialize1.java ObjectOutputStream 继承了 OutputStream 类,同时实现了 ObjectOutput 接口,提供将对象系列化写入 stream 的功能。
Java输入与输出 -> 流 -> 对象系列化 -> ObjectInputStream Serialize2.java ObjectInputStream 类继承了 InputStream 类,同时实现了 ObjectInput 接口,用于从流中读取对象。
线程 -> Runtime类与Process类 RunAndPro1.java
RunAndPro2.java
在 Java 中,有一个叫做 runtime object 的对象。这个对象提供 JVM 启动系统接口,同时负责运行平台的基本程序(非 Java 类),也提供有关运行平台的信息。
线程 -> 创建线程 Thread1.java 创建线程的方法有点复杂,但是只要理解了原理,我们就能轻而易举地掌握它。在 Java 中,线程也是一种对象,但并非任何对象都可以成为线程,只有实现了 Runnable 接口的类的对象才有资格成为线程,即实现了 Runnable 接口是对象转变为线程的一个必要条件。
线程 -> 创建线程 -> 创建线程的另一种方法 Thread2.java
Thread3.java
Thread3_1.java
Thread 类本身也实现了 Runnable 接口。所以,我们可以构建一个类,让它继承 Thread 类,并覆盖继承而来的 run() 方法,通过创建这个类的对象,从而创建一个线程。
线程 -> 多线程 Thread4.java
Thread5.java
Alone14_1.java
如果我们同时启动多个线程,这些线程就会在 CPU 上按照启动顺序在给定的时间内轮流执行。
线程 -> 线程的优先级 Thread6.java 优先级(priority)高的线程通常会比优先级低的线程获得更多的执行时间。如果想让某个线程获得比其它线程更多的运行时间,您只需将其优先级设得高一些就行了。一个线程创建之后,我们可以通过在线程中调用 set Priority() 方法来设置它的优先级。
线程 -> 线程的休眠与唤醒 Thread7.java
Thread8.java
Alone14_2.java
Thread9.java
线程休眠指线程暂时处于等待的一种状态。调用 Thread 类的 sleep() 方法可以使线程在指定的时间内处于休眠状态。线程在休眠时间结束后,会重新执行未尽的义务。
线程 -> 线程让步 Thread10.java 调用线程类的 yield() 方法,会使当前正在执行的线程对象退出运行状态,使得其他线程得以运行,这通常被称为线程的让步。
线程-线程同步 Synchronization1.java
Synchronization2.java
Java 语言支持多个线程,并且具有并发能力,这打打提高了计算机的处理能力。但是,在两个或两个以上的线程需要共享同一资源时,多线程的使用会带来多种问题。只有获得共享资源权限的线程才能执行某种任务的情况,我们称之为线程的同步化(synchronization)。
线程 -> 线程同步 -> 同步块 Synchronization3.java
Synchronization4.java
Alone14_3.java
同步块是使具有某个对象的 monitor 的线程获取运行权限的一种方法。monitor 是所有 Java 对象都具有的同步保障对象,将其想象成对象的权限即可。
线程 -> 线程同步 -> 同步化方法 Synchronization5.java
Alone14_4.java
同步块只对大括弧内的代码段进行同步,与之相对,同步化方法会对整个方法进行同步。
线程 -> 线程同步 -> 生产者与消费者 HMaker.java
Hassistant.java
Synchronization6.java
线程 -> 线程同步 -> 多消费者 Synchronization7.java
线程 -> stop()、suspend()和resume() Deprecation1.java
Deprecation2.java
常用API之二 -> Collection接口
常用API之二 -> Collection接口 -> Set接口 HashSet1.java
HashSet2.java
常用API之二 -> Collection接口 -> List接口 Vector1.java
Vector2.java
Alone15_1.java
常用API之二 -> Collection接口 -> Map接口 HashTable1.java
常用API之二 -> java.util.Random类 Random1.java
Random2.java
Alone15_2.java
常用API之二 -> java.util.Arrays类 Arrays1.java
Arrays2.java
Arrays3.java
常用API之二 -> java.util.StringTokenizer类 Tokenizer1.java
Alone15_3.java
常用API之二 -> java.util.Calender类 Calendar1.java
Calendar2.java
Calendar3.java
常用API之三 -> 日期API 时间日期格式化代码参考:DateTimeFormat.java
常用API之三 -> 日期API -> java.time.LocalDate类 LocalDate1.java
只含年月日的日期对象
常用API之三 -> 日期API -> java.time.LocalTime类 LocalTime1.java
只含时分秒的时间对象
常用API之三 -> 日期API -> java.time.LocalDateTime类 LocalDateTime1.java
同时含有年月日时分秒的日期对象