# 1 常量和变量## 1.1 常量### 1.1.1 定义程序中固定不变化的值### 1.1.2 分类#### 1.1.2.1 字面值常量##### 1.1.2.1.1 整型常量- 二进制整数:以0B或0b开头,如:`int a=0B110;` - 八进制整数:以0开头,如:`int a=012;` - 十进制整数:以123456789开头,如:`int a=123;` - 十六进制整数:以0X或0x开头,如:`int a=0x12;`##### 1.1.2.1.2 浮点型常量- 十进制形式:3.14,168.0,.18 - 科学计数法形式:3.14e2,3.14E2,1000E-2科学计数法表达式返回的结果是double类型。##### 1.1.2.1.3 布尔常量true,false 等等。##### 1.1.2.1.4 字符常量有3种表示形式:1. 直接使用单个字符来指定字符常量,格式如'A','7'; 2. 直接作为十进制整数数值使用,但是数据范围在[0,65535],格式如97,但是但因出来的值依然是ASCII码表对应的符号,如97打印出来的是字符a。 3. 和上面的2一样,只不过表示的是16进制的数值,格式如'\uX',X表示16进制整数;如:97的16进制是61。那么'\u0061'打印出来也是a。#### 1.1.2.2 定义的final常量后讲## 1.2 变量### 1.2.1 定义表示存储空间,可用来存放某一类型的常量,没有固定值,并可以重复使用,也可以用来存储某种类型的未知数据。### 1.2.2 特点1. 占据着内存中的某一块存储区域 2. 该区域有自己的名称(变量名)和类型(数据类型) 3. 可以被重复使用 4. 该区域的数据可以在同一类型范围内不断变化### 1.2.3 使用变量赋值的方式有:1. 先声明,后赋值 2. 声明的同时赋值变量必须初始化(赋值)之后才能使用,初始化才是真正的在内存中分配空间。只声明,不赋值的话就不能使用。### 1.2.4 分类#### 1.2.4.1 成员变量##### 1.2.4.1.1 定义在类体的变量部分中定义的变量,也称为字段。#### 1.2.4.2 局部变量##### 1.2.4.2.1 定义变量除了成员变量,其他的都是局部变量。#### 1.2.4.3 作用域- 成员变量:在所定义的类中起作用 - 局部变量:所在的最近的{}里面起作用# 2 数据类型## 2.1 基本数据类型### 2.1.1 数值型#### 2.1.1.1 整数类型| 数据类型 | 占位 | 数据范围 | 默认值 | | :------: | :---: | :--------------: | :----: | | byte | 1字节 | [-2^7^,2^7^-1] | 0 | | short | 2字节 | [-2^15^,2^15^-1] | 0 | | int | 4字节 | [-2^31^,2^31^-1] | 0 | | long | 8字节 | [-2^63^,2^63^-1] | 0L |Java语言的整型常量默认是int型,声明long类型变量后加上“l”或“L”,因小写的容易和数字1相混淆,建议使用大写L。#### 2.1.1.2 小数类型| 数据类型 | 占位 | 数据范围 | 默认值 | | :------: | :---: | :----------------: | :----: | | float | 4字节 | [1.4E-45,3.4E38] | 0.0F | | double | 8字节 | [4.9E-324,1.7E308] | 0.0D |float表示单精度类型,double表示双精度类型,但是二者都不能表示精确的小数。Java语言的浮点型常量默认是double型,若要声明一个常量为float型,则需在常量后加上f或F,double常量后面的D或d可省略。### 2.1.2 字符型| 数据类型 | 占位 | 数据范围 | 默认值 | | -------- | ----- | ----------- | -------- | | char | 2字节 | [0,2^16^-1] | '\u0000' |表示16位的无符号整数或者Unicode字符,Java对字符采用Unicode字符编码。### 2.1.3 布尔型| 数据类型 | 占位 | 数据范围 | 默认值 | | :------: | :--: | :---------: | :----: | | boolean | 1位 | false,true | false |该类型的值只能是true或false,表示真或假。不可以使用0或非0的证书来代替false和true,区分于C语言。(其实在JVM中对boolean的处理也是用0表示false,非0表示true的)false和true是boolean的常量。### 2.1.4 类型转换#### 2.1.4.1 概述`在8大基本数据类型中,boolean不属于数值类型,不参与转换`转换规则其实就是各自数据类型的空间大小:可以赋值------->[byte]--[short,char]--[int]--[long]--[float]--[double]<-------不可以赋值```java byte b=3; int a=b; ```#### 2.1.4.2 自动类型转换自动类型转换,也成为“隐式类型转换”。当把小范围数据类型的数值或变量赋给另一个大范围数据类型变量,可以完成自动类型转换。#### 2.1.4.3 强制类型转换当把大范围数据类型的数值或变量赋给另一个小范围类型变量时,不能自动完成转换,需要加上强制转换符,但这样的操作可能造成数据精度的降低或溢出,所以使用时要格外注意。```java double pi=3.14; int a=(int)pi; //此时a=3 ```#### 2.1.4.4 表达式类型的自动提升当一个算术表达式中包含多个基本数据类型(boolean除外)的值时,整个算术表达式的数据类型将在数据运算时出现类型自动提升,其规则是:1. 所有的 byte,short,char类型被自动提升到int类型 2. 整个表达式的最终结果类型被提升到表达式中类型最高的类型## 2.2 引用数据类型### 2.2.1 有哪些?字符串、数组、类、对象、接口等等。### 2.2.2 字符串链接字符串使用“+”字符串拼接:字符串和任意数据类型相连接,结果都是字符串类型。 ### 2.2.3 数组#### 2.2.3.1 概念- 数组是有序存储多个同一种数据类型元素的集合。也可以看成是一个容器。 - 数组既可以存储基本数据类型,也可以存储引用数据类型。#### 2.2.3.2 一维数组##### 2.2.3.2.1 声明###### 2.2.3.2.1.1 动态初始化先创建之后再赋值```java int[] arr=new int[5]; ```###### 2.2.3.2.1.2 静态初始化创建的同时赋值```java int[] arr=new int[]{11,22,33,44,55}; int[] arr={11,22,33,44,55}; //简写 ```#### 2.2.3.3 多维数组##### 2.2.3.3.1 声明方式```java class test {public static void main(String[] args) {//声明方式1int[][] arr1=new int[3][2];//这个二维数组中有3个一维数组,每个一维数组中有2个元素。//声明方式2int[][] arr2=new int[3][];//二维数组中有三个一维数组,三个一维数组都没有被赋值arr2[0]=new int[3];//第一个一维数组中可以存储三个int值arr2[1]=new int[5];//第二个一维数组中可以存储五个int值//声明方式3int[][] arr3={{1,2},{1,2,3},{4}};} } ```#### 2.2.3.4 基本操作##### 2.2.3.4.1 获取指定索引元素```java int[] arr=new int[]{1,4,7,3,8}; int result=arr[2]; System.out.println(result); //8 ```##### 2.2.3.4.2 指定索引设置元素```java int[] arr=new int[]{1,4,7,3,8}; int result=arr[2]; System.out.println(result); //7 arr[2]=50; result=arr[2]; System.out.println(result); //50 ```##### 2.2.3.4.3 获取数组长度```java int[] arr=new int[]{1,4,7,3,8}; int result=arr.length; System.out.println(result); //5 ```##### 2.2.3.4.4 数组深拷贝`arraycopy(Object src, int srcPos, Object dest, int destPos, int length);`- src - 源数组。 - srcPos - 源数组中的起始位置。 - dest - 目标数组。 - destPos - 目标数据中的起始位置。 - length - 要复制的数组元素的数量。```java import java.util.Arrays;public class test {public static void main(String[] args) throws Exception {int[] formArray = {101, 102, 103, 104, 105, 106};int[] toArray = {201, 202, 203, 204, 205, 206, 207};System.arraycopy(formArray, 2, toArray, 3, 2);System.out.println(Arrays.toString(toArray));//[201, 202, 203, 103, 104, 206, 207] } } ```#### 2.2.3.5 数组工具类Arrays##### 2.2.3.5.1 数组转换成字符串```java import java.util.Arrays;public class test {public static void main(String[] args) {int[] arr=new int[]{1,6,7,4};System.out.println(Arrays.toString(arr)); //[1, 6, 7, 4] } } ```##### 2.2.3.5.2 升序排列数组中的元素- 升序排列所有元素 - 升序排列指定索引区间元素```java import java.util.Arrays;public class test {public static void main(String[] args) {int[] arr1=new int[]{8,6,3,1};int[] arr2=new int[]{8,6,3,1};Arrays.sort(arr1);System.out.println(Arrays.toString(arr1)); //[1, 3, 6, 8]Arrays.sort(arr2,0,2); //Arrays.sort(需要排序的数组,要排序的第一个元素的索引(包括),要排序的最后一个元素的索引(不包括))System.out.println(Arrays.toString(arr2)); //[6, 8, 3, 1] } } ```##### 2.2.3.5.3 二分查找指定元素- 用法:- 查找全部索引区间内的指定元素的索引- 查找指定索引区间内的指定元素的索引 - 注意点:- 此法为二分搜索法,故查询前需要用sort()方法将数组排序,如果数组没有排序,则结果是不确定的。- 如果数组中含有多个指定值的元素,则无法保证找到的是哪一个。- 如果key在数组中,则返回搜索值的索引,否则返回值是(插入点+1)*(-1)。```java import java.util.Arrays;public class test {public static void main(String[] args) {int a[] = new int[]{1, 3, 4, 6, 8, 9};//binarySearch(object[ ], object key);int x1 = Arrays.binarySearch(a, 5); //-4int x2 = Arrays.binarySearch(a, 4); //2int x3 = Arrays.binarySearch(a, 0); //-1int x4 = Arrays.binarySearch(a, 10); //-7//binarySearch(object[ ], int fromIndex, int endIndex, object key);int x5 = Arrays.binarySearch(a, 1, 4, 5); //-4int x6 = Arrays.binarySearch(a, 1, 4, 4); //2int x7 = Arrays.binarySearch(a, 1, 4, 0); //-2int x8 = Arrays.binarySearch(a, 1, 3, 10); //-4 } } ```##### 2.2.3.5.4 从头部深拷贝数组`Arrays.copyOf(被拷贝的数组, 新的数组长度);````java import java.util.Arrays;public class test {public static void main(String[] args) throws Exception {int[] formArray = {101, 102, 103, 104, 105, 106};int[] toArray = {1, 2, 3, 4};System.out.println(Arrays.toString(toArray)); //[1, 2, 3, 4]toArray = Arrays.copyOf(formArray, 3);System.out.println(Arrays.toString(toArray)); //[101, 102, 103] } } ```##### 2.2.3.5.5 指定位置深拷贝数组```java import java.util.Arrays;public class test {public static void main(String[] args) throws Exception {int[] formArray = {101, 102, 103, 104, 105, 106};int[] toArray = {1, 2, 3, 4};System.out.println(Arrays.toString(toArray)); //[1, 2, 3, 4]toArray = Arrays.copyOfRange(formArray, 2,4);System.out.println(Arrays.toString(toArray)); //[103, 104] } } ```##### 2.2.3.5.6 未整理的```java static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。 static <T> int binarySearch(T[] a, int fromIndex, int toIndex, T key, Comparator<? super T> c) 使用二分搜索法来搜索指定数组的范围,以获得指定对象。 static <T> int binarySearch(T[] a, T key, Comparator<? super T> c) 使用二分搜索法来搜索指定数组,以获得指定对象。static <T> T[] copyOf(T[] original, int newLength) 复制指定的数组,截取或用 null 填充(如有必要),以使副本具有指定的长度。 static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) 复制指定的数组,截取或用 null 填充(如有必要),以使副本具有指定的长度。 static <T> T[] copyOfRange(T[] original, int from, int to) 将指定数组的指定范围复制到一个新数组。 static <T,U> T[] copyOfRange(U[] original, int from, int to, Class<? extends T[]> newType) 将指定数组的指定范围复制到一个新数组。 static boolean deepEquals(Object[] a1, Object[] a2) 如果两个指定数组彼此是深层相等 的,则返回 true。 static int deepHashCode(Object[] a) 基于指定数组的“深层内容”返回哈希码。 static String deepToString(Object[] a) 返回指定数组“深层内容”的字符串表示形式。 static boolean equals(boolean[] a, boolean[] a2) 如果两个指定的 boolean 型数组彼此相等,则返回 true。 static boolean equals(byte[] a, byte[] a2) 如果两个指定的 byte 型数组彼此相等,则返回 true。 static boolean equals(char[] a, char[] a2) 如果两个指定的 char 型数组彼此相等,则返回 true。 static boolean equals(double[] a, double[] a2) 如果两个指定的 double 型数组彼此相等,则返回 true。 static boolean equals(float[] a, float[] a2) 如果两个指定的 float 型数组彼此相等,则返回 true。 static boolean equals(int[] a, int[] a2) 如果两个指定的 int 型数组彼此相等,则返回 true。 static boolean equals(long[] a, long[] a2) 如果两个指定的 long 型数组彼此相等,则返回 true。 static boolean equals(Object[] a, Object[] a2) 如果两个指定的 Objects 数组彼此相等,则返回 true。 static boolean equals(short[] a, short[] a2) 如果两个指定的 short 型数组彼此相等,则返回 true。 static void fill(boolean[] a, boolean val) 将指定的 boolean 值分配给指定 boolean 型数组的每个元素。 static void fill(boolean[] a, int fromIndex, int toIndex, boolean val) 将指定的 boolean 值分配给指定 boolean 型数组指定范围中的每个元素。 static void fill(byte[] a, byte val) 将指定的 byte 值分配给指定 byte 节型数组的每个元素。 static void fill(byte[] a, int fromIndex, int toIndex, byte val) 将指定的 byte 值分配给指定 byte 型数组指定范围中的每个元素。 static void fill(char[] a, char val) 将指定的 char 值分配给指定 char 型数组的每个元素。 static void fill(char[] a, int fromIndex, int toIndex, char val) 将指定的 char 值分配给指定 char 型数组指定范围中的每个元素。 static void fill(double[] a, double val) 将指定的 double 值分配给指定 double 型数组的每个元素。 static void fill(double[] a, int fromIndex, int toIndex, double val) 将指定的 double 值分配给指定 double 型数组指定范围中的每个元素。 static void fill(float[] a, float val) 将指定的 float 值分配给指定 float 型数组的每个元素。 static void fill(float[] a, int fromIndex, int toIndex, float val) 将指定的 float 值分配给指定 float 型数组指定范围中的每个元素。 static void fill(int[] a, int val) 将指定的 int 值分配给指定 int 型数组的每个元素。 static void fill(int[] a, int fromIndex, int toIndex, int val) 将指定的 int 值分配给指定 int 型数组指定范围中的每个元素。 static void fill(long[] a, int fromIndex, int toIndex, long val) 将指定的 long 值分配给指定 long 型数组指定范围中的每个元素。 static void fill(long[] a, long val) 将指定的 long 值分配给指定 long 型数组的每个元素。 static void fill(Object[] a, int fromIndex, int toIndex, Object val) 将指定的 Object 引用分配给指定 Object 数组指定范围中的每个元素。 static void fill(Object[] a, Object val) 将指定的 Object 引用分配给指定 Object 数组的每个元素。 static void fill(short[] a, int fromIndex, int toIndex, short val) 将指定的 short 值分配给指定 short 型数组指定范围中的每个元素。 static void fill(short[] a, short val) 将指定的 short 值分配给指定 short 型数组的每个元素。 static int hashCode(boolean[] a) 基于指定数组的内容返回哈希码。 static int hashCode(byte[] a) 基于指定数组的内容返回哈希码。 static int hashCode(char[] a) 基于指定数组的内容返回哈希码。 static int hashCode(double[] a) 基于指定数组的内容返回哈希码。 static int hashCode(float[] a) 基于指定数组的内容返回哈希码。 static int hashCode(int[] a) 基于指定数组的内容返回哈希码。 static int hashCode(long[] a) 基于指定数组的内容返回哈希码。 static int hashCode(Object[] a) 基于指定数组的内容返回哈希码。 static int hashCode(short[] a) 基于指定数组的内容返回哈希码。 static <T> void sort(T[] a, Comparator<? super T> c) 根据指定比较器产生的顺序对指定对象数组进行排序。 static <T> void sort(T[] a, int fromIndex, int toIndex, Comparator<? super T> c) 根据指定比较器产生的顺序对指定对象数组的指定范围进行排序。 ```### 2.2.4 类型转换#### 2.2.4.1 自动类型转换把子类对象赋给父类变量(多态)。#### 2.2.4.2 强制类型转换把父类类型对象赋给子类类型变量(当时该父类类型变量的真实类型应该是子类类型)。## 2.3 关于默认值一般来说,变量只声明没有赋值的时候,局部变量不会被初始化(也就是没有默认值),只有类的成员变量才会被初始化(有默认值)。```java public class test{private static int i;public static void main (String args[]){int j;System.out.println(i); //输出0System.out.println(j); //j未初始化,所以报错 } } ```数组类型声明的时候就已经赋值了,所以数组类型当做局部变量使用的时候只声明,也会有默认值。```java import java.util.Arrays;public class test {public static void main(String[] args) {int[] arr=new int[3];System.out.println(Arrays.toString(arr)); //[0, 0, 0] } } ```# 3 运算符 ## 3.1 算术运算符| 运算符 | 运算 | 范例 | 结果 | | :----: | :------------------------: | :--------: | :------: | | + | 正号 | +3 | 3 | | - | 负号 | b=4;-b; | -4 | | + | 加 | 5+5 | 10 | | - | 减 | 6-4 | 2 | | * | 乘 | 3*4 | 12 | | / | 除 | 5/5 | 1 | | % | 取模 | 14%3 | 2 | | ++a | 自增(前),先运算、后赋值 | a=2;b=++a; | a=3;b=3; | | a++ | 自增(后),先赋值、后运算 | a=2;b=a++; | a=3;b=2; | | --a | 自减(前),先运算、后赋值 | a=2;b=--a; | a=1;b=1; | | a-- | 自减(后),先赋值、后运算 | a=2;b=a--; | a=1;b=2; | | + | 字符串相加 | "he"+"llo" | "hello" |- 加号、减号:- 两个数值相加得到的是数值- 两个字符相加得到的是ASCII码表值 `System.out.println('a'+'b'); //195`- 两个字符串相加时表示将两个字符串连接在一起 - 除号:- 整数在使用除号操作时,得到的结果仍为整数(小数部分忽略),当整数除以0的时候,会引发算术异常- 正无穷大(Infinity):正浮点类型除以0,或者正整数除以0.0(0的浮点数)时结果为Infinity `double d=3.14;System.out.println(d/0); //Infinity`- 负无穷大(-Infinity):负浮点类型除以0,或者负整数除以0.0(0的浮点数)时结果为-Infinity `double d=-3.14;System.out.println(d/0); //-Infinity`- NaN(Not a Number):0除以0,至少有一个0是0的浮点数,结果为NaN,不区分正负 `System.out.println((-0.0000)/0); //NaN`- 注意:无穷大和NaN都属于double浮点类型,但是所有正无穷大都是相等的,所有负无穷大也是相等的,NaN永远不相等,也不等于自己 - 取模:模数的符号忽略不计,结果的正负取决于被模数 `System.out.println((-10)%(-3)); //-1` ## 3.2 赋值运算符| 运算符 | 运算 | 范例 | 结果 | | :----: | :--------------: | :-----------: | :------: | | = | 赋值 | a=3;b=2; | a=3;b=2; | | += | a+=b相当于a=a+b | a=3;b=2;a+=b; | a=5;b=2; | | -= | a-=b相当于a=a-b | a=3;b=2;a-=b; | a=1;b=2; | | *= | a*=b相当于a=a\*b | a=3;b=2;a*=b; | a=6;b=2; | | /= | a/=b相当于a=a/b | a=3;b=2;a/=b; | a=1;b=2; | | %= | a%=b相当于a=a%b | a=3;b=2;a%=b; | a=1;b=2; |```java short s=3; s+=5; 相当于 s=(short)(s+5); ```## 3.3 比较运算符| 运算符 | 运算 | 范例 | 结果 | | :--------: | :----------------: | :-----------------------: | :---: | | == | 相等于 | 4==3 | false | | != | 不等于 | 4!=3 | true | | < | 小于 | 4<3 | false | | > | 大于 | 4>3 | true | | <= | 小于等于 | 4<=3 | false | | \>= | 大于等于 | 4>=3 | true | | instanceof | 检查是否是类的对象 | "hello" instanceof String | true |instanceof:被检查的对象 instanceof 被检查的对象的真实类型 或 真实类型的祖先类型。``` java public class test{public static void main(String[] args) {dog a=new smalldog();System.out.println(a instanceof animal); //trueSystem.out.println(a instanceof smalldog); //true } }class animal{} class dog extends animal{} class smalldog extends dog{} ```## 3.4 三元运算符判断条件为true ==> 结果是值1,判断条件为false ==> 结果是值2。```java int a = 50; int b = 150; int result = 100 > 10 ? b : a;判断条件 值1 值2 System.out.println(result); //150 ```## 3.5 逻辑运算符| 运算符 | 运算 | 范例 | 结果 | | :----: | :---------: | :-----------: | :---: | | & | AND(与) | false&true | false | | && | AND(短路) | false&&true | false | | \| | OR(或) | false\|true | true | | \|\| | OR(短路) | false\|\|true | true | | ^ | XOR(异或) | false^true | true | | ! | Not(非) | !true | false |短路:只看左边操作数能知道最后结果时不计算右边操作数。^:左右两边操作数,不同则是true,相同则是false。## 3.6 位运算符| 逻辑运算符 | 描述 | | :--------: | :----------------------: | | & | 按位与 | | \| | 按位或 | | ^ | 异或(相同为0,不同为1) | | ~ | 取反 | | << | 左位移 | | \>> | 右位移 | | \>>> | 无符号右位移 |- &:两个都是1,结果是1,否则结果是0 - |:两个当中只要有一个是1,结果就是1 - ^:两个数值相同,结果是0,否则结果是1 - ~:取反,把0换成1,把1换成0 - <<:整体左移指定位数,左移之后的“空”使用“0”来补充 - \>>:整体右移指定位数,右移之后的“空”使用“符号位”来补充,若是正数,使用“0”来补充,若是负数,使用“1”补充 - \>>>:整体右移指定位数,右移之后空位使用“0”来补充# 4 流程语句## 4.1 选择结构### 4.1.1 if语句```java //if结构 if(条件){}//if else结构 if(条件){}else{}//if else-if结构 if(条件){}else if(条件){}//if else-if else结构 if(条件){}else if(条件){}eles{} ```### 4.1.2 switch语句```java class test {public static void main(String[] args) {String name="pakhm";String gender="man";switch (gender){ case "man":System.out.println(name+"是一位"+gender+",喜欢健身");break;case "woman":System.out.println(name+"是一位"+gender+",喜欢狂街");break;default:System.out.println("无法识别性别");break;}} } ```注意点:- switch语句只有遇到break和右大括号才会停止 - case后面只能是常量,不能是变量 - default可以加,也可以不加## 4.2 循环结构### 4.2.1 while循环```java class test {public static void main(String[] args) {int x = 1;while (x <= 5) {System.out.println("x=" + x);x++;}} } ```### 4.2.2 do while循环```java class test {public static void main(String[] args) {int i = 1;do {System.out.println("i=" + i);i++;}while (i <= 10);} } ```### 4.2.3 for循环#### 4.2.3.1 普通for循环```java class test {public static void main(String[] args) {for(int i=1;i<=5;i++){System.out.println("i="+i);}} } ```#### 4.2.3.2 增强for循环```java public class test{public static void main(String[] args){int[] arr={11,22,33,44,55};for(int i:arr){System.out.println(i);}} } ```#### 4.2.3.3 无限for循环```java public class test{public static void main(String[] args){for(;;){System.out.println("无限for循环");}} } ```### 4.2.4 嵌套循环性能优化1. 循环次数少的放在外面,循环次数多的放在里面。 2. 将循环变量的实例化放在循环外。 ```java class test {public static void main(String[] args) {int i;int j;int k;for (i = 0; i < 10; i++) {for (j = 0; j < 100; j++) {for (k = 0; k < 1000; k++) {System.out.println(i + j + k);}}}} } ``` ## 4.3 控制选择、循环结构语句### 4.3.1 breakswitch,for,while,do while中使用。终止离break最近的选择、循环结构。### 4.3.2 continuefor,while,do while中使用。跳出离continue最近的循环结构当中的本次循环。### 4.3.3 标号可以精确的使用break和continue。```java class test {public static void main(String[] args) {a:for(int i=1;i<=5;i++){System.out.println("i="+i);b:for (int k=3;k<=5;k++){System.out.println("b循环");if(k==4){break a;}}}} } ```### 4.3.4 return结束当前所在的方法。# 5 方法## 5.1 格式```java [修饰符] 返回值类型 方法名([参数类型 参数名1,参数类型 参数名2...]) {方法体语句;[return 返回值;] } ```## 5.2 使用如果方法使用了static修饰符: 方法所在的类的名称.方法名([参数]);如果方法没有使用static修饰符: 方法所在类的对象来调用## 5.3 定义的位置1. 在类中定义,在Java中最小的程序单元是类 2. 方法定义在其他方法之外,方法和方法是兄弟关系 3. 方法定义的先后顺序不影响## 5.4 重载### 5.4.1 定义在Java中,同一个类中的多个方法可以有相同的方法名称,但是有不同的参数列表,这就称为方法重载(method overloading)。### 5.4.2 规则1. 必须是在同一个类中。 2. 方法名相同。 3. 方法参数的个数、顺序或类型不同。 4. 与方法的修饰符或返回值没有关系。 5. 多个方法重载时,一般是参数少的调用参数多的。## 5.5 可变长参数- 可变长参数底层是用数组做的。 - 调用方法的时候可变长参数可以不写。 - 若除了可变长参数还有其它参数,可变长参数一定要放在最后。```java import java.util.Arrays;public class test {public static void main(String[] args) {kebianchang("jiongwen1"); //jiongwen1,[]kebianchang("jiongwen2",1,2,2,2,2); //jiongwen2,[1, 2, 2, 2, 2] }static void kebianchang(String str,int ... shuzi){System.out.println(str);System.out.println(Arrays.toString(shuzi));} } ```# 6 类和对象## 6.1 类### 6.1.1 概述具有相同特性(状态)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有特性,对象的状态,用成员变量来描述。类具有功能,对象的行为,用方法来描述。类是对象的模板。创建一个对象,就是使用一个类作为构建该对象的基础。### 6.1.2 定义#### 6.1.2.1 格式```java [修饰符] class 类名{0~N个成员变量(字段)0~N个成员方法 } ```#### 6.1.2.2 注意事项1. 如果类使用了public修饰符,必须保证当前文件名和当前类名相同。 2. Java源文件中不必有一个public类,如果没有public类的话,那么文件名可以是任意合法名称,且编译完成之后如果该源文件中有多个独立的类,则会生成多个对应的.class文件。 3. 类名使用名称表示,类表示某一类事物,首字母大写,如果是多个单词组成使用,用驼峰表示法。 4. 在面向对象的过程中,定义类的时候,专门为描述对象提供一个类,该类不需要main方法。### 6.1.3 构造器#### 6.1.3.1 作用1. 创建对象,凡是必须和new一起使用。 2. 完成对象的初始化操作。```java 类型 s1 = new 类名(); //根据类来创建对象,使用构造函数 ``````java class Student{String name;boolean isFee;Student(){ //完成对象的初始化操作。isFee = false;}void fees(){isFee = true;} } ```#### 6.1.3.2 特点1. 编译器在编译源文件的时候,会创建一个缺省的构造器。如果我们显示定义了一个构造器,则编译器不再创建默认构造器。 2. 构造器的名称和当前所在类的名称相同。 3. 进制定义返回类型。 4. 在构造器中,不需要使用return语句。其实构造器是有返回值的,返回的是当前创建对象的引用。#### 6.1.3.3 编译器创建的默认构造器的特点1. 符合构造器特点。 2. 无参数的。 3. 无方法体。 4. 如果类A没有使用public修饰,则编译器创建的构造器也没有public修饰,如果类A使用public修饰,则编译器创建的构造器也有public修饰。#### 6.1.3.4 重载构造器重载的时候一般是参数少的调用参数多的。this([参数])的意思是调用这个类的其他构造器。```java class Person{String name;int age;Person(){ //构造器重载 }Person(String name){ //构造器重载this(name,0)}Person(String name,int age){this.name=name;this.age=age;} } ```### 6.1.4 成员变量获取值、赋值`方式1````java class test{String name;public static void main(String[] args) {test t1=new test();t1.name="pakhm";System.out.println(t1.name);} } ````方式2````java class test{String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public static void main(String[] args) {test t1=new test();t1.setName("pakhm");System.out.println(t1.getName());} } ```## 6.2 对象### 6.2.1 概述对象是人们要进行研究的任何事物,一切事物都可以认为是对象。对象具有状态和行为: 对象具有状态,比如姓名,年龄,性别等。 对象还有操作,比如吃饭,睡觉,写代码等。对象可以定义成包含状态和行为的一个实体,对象也称为实例。### 6.2.2 定义格式```java 类型 s1 = new 类名(); //根据类来创建对象,使用类的构造函数来创建对象 s1.name="pakhm"; //设置成员变量 String n1=s1.name; //获取成员变量 s1.cook(参数); //使用对象的方法 ```### 6.2.3 匿名对象匿名对象只是在堆中开辟一块新的内存空间,但是没有把该空间地址赋给任何变量。因为没有名称,匿名对象仅仅只能使用一次,一般的,把匿名对象作为方法的实参传递。```java new 类名().cook(参数); ```## 6.3 类和对象的关系对象是类的实例,类是对象的模板。## 6.4 修饰符### 6.4.1 静态#### 6.4.1.1 概述static修饰符表示静态的,可修饰字段、方法、内部类,其修饰的成员属于类,也就是说static修饰的资源属于类级别,而不是对象级别。#### 6.4.1.2 作用用来区别字段、方法、内部类、初始化代码块是属于对象还是属于类本身。#### 6.4.1.3 特点1. static修饰的成员(字段、方法),随着所在的类的加载而加载。2. 优先于对象的存在。3. static修饰的成员被该类型的所有对象所共享。根据该类创建出来的任何对象,都可以访问static成员。表面上通过对象去访问static成员,其本质依然使用类名(编译类型)访问,和对象没有任何关系。4. 直接使用类名访问static成员。static修饰的成员直接属于类,不属于对象,所以可以直接使用类名(编译类型)访问static成员。#### 6.4.1.4 注意点static不能和this,super一起使用。### 6.4.2 访问权限- private:表示私有的,表示类访问权限。只能在本类中访问,离开本类之后不能直接访问。 - 不写(缺省):表示包私有,表示包访问权限。访问者的包必须和当前定义类的包相同才能访问。 - protected:表示子类访问权限,同包中的可以访问,即使不同包,但是有继承关系,也可以访问。 - public:表示全局的公共访问权限,可以在当前项目中任何地方都可以访问。如果类使用了public修饰符,必须保证当前文件名和当前类名相同。| 修饰符 | 不可以修饰谁? | 类内部 | 同一个包 | 子类 | 任何地方 | | ------------ | -------------- | :------: | :------: | :------: | :------: | | private | 外部类 | 可以访问 | | | | | 不写(缺省) | | 可以访问 | 可以访问 | | | | protected | 外部类 | 可以访问 | 可以访问 | 可以访问 | | | public | | 可以访问 | 可以访问 | 可以访问 | 可以访问 |## 6.5 成员### 6.5.1 类中的成员字段,方法,内部类。### 6.5.2 类成员类中的成员中使用static修饰的成员。### 6.5.3 实例成员类中的成员中没有使用static修饰的成员。### 6.5.4 成员之间访问规则- 类成员方法可以访问:- 类成员变量- 类成员方法 - 实例成员方法可以访问:- 类成员变量- 实例成员变量- 类成员方法- 实例成员方法```java public class test {static String str1="static";String str2="noStatic";static void fun1(){System.out.println("fun1");fun2();System.out.println(str1);}static void fun2(){System.out.println("fun2");}void fun3(){System.out.println("fun3");System.out.println(str1);System.out.println(str2);fun1();fun4();}void fun4(){System.out.println("fun4");}public static void main(String[] args) {test t1=new test();t1.fun3();} }//输出结果: //fun3 //static //noStatic //fun1 //fun2 //static //fun4 ```## 6.6 this关键字### 6.6.1 概述this主要存在于两个位置。- 构造器中:表示当前创建的对象。 - 方法中:哪一个对象调用this所在的方法,那么此时this就表示哪一个对象。### 6.6.2 使用场景 `1.解决成员变量和参数(局部变量)之间的二义性,必须使用````java public class car {private int 车轮 = 4 ;public int get车轮() {return 车轮;}public void set车轮(int 车轮) {this.车轮 = 车轮;} } ````2.同类中实例方法间互调(此时可以省略this,但是不建议省略)````java class test {void fun1(){System.out.println("fun1");}void fun2(){System.out.println("fun2");this.fun1();} } ````3.将this作为参数传递给另一个方法````java public boolean matches(String regex){return Pattern.matches(regex, this); } ````4.将this作为方法的返回值(链式方法编程)````java public StringBuilder append(int i){super.append(i);return this; } ````5.构造器重载的互调,this([参数])必须卸载构造方法第一行`this([参数])的意思是调用这个类的其他构造器。```java class Person{String name;int age;Person(String name,int age){this.name=name;this.age=age;}Person(String name){ //构造器重载this(name,0)}Person(){ //构造器重载this(null,0)}} ````6.static不能和this一起使用````java class test {static void fun1(){System.out.println("fun1");}static void fun2(){System.out.println("fun2");this.fun1(); //此处报错 } } ```## 6.7 JavaBean### 6.7.1 概述JavaBean是Java中一种特殊的类,可以将多个对象封装到一个对象(bean)中。特点是可序列化,提供无参构造器,提供getter方法和setter方法访问对象的属性。名称中的“Bean”是用于Java的可重用软件组件的惯用叫法。### 6.7.2 规范1. 类必须使用public修饰,所有属性(JavaBean当中的属性相当于普通类当中的成员变量)为private。 2. 必须保证有公共无参数构造器,即使手动提供了带参数的构造器,也得提供无参数构造器。 3. 包含了属性的操作手段(给属性赋值,获取属性值)。 4. 实现serializable接口### 6.7.3 长什么样?```java import java.io.Serializable;public class Email implements Serializable {// serialVersionUID 值private static final long serialVersionUID = 1L;private String mailAdd;private boolean eamil;public Email() {}public Email(String mailAdd) {this.mailAdd = mailAdd;}public boolean isEamil() {return eamil;}public void setEamil(boolean eamil) {this.eamil = eamil;}public String getMailAdd() {return mailAdd;}public void setMailAdd(String mailAdd) {this.mailAdd = mailAdd;} } ```## 6.8 继承### 6.8.1 概述基于某个父类对对象的定义加以扩展,而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类所没有的定义,或者覆写父类中的某些特性。### 6.8.2 语法格式在定义子类的时候来表明自己需要扩展于哪一个父类。```java public class 子类类名 extends 父类类名{//编写自己特有的状态和行为 } ```### 6.8.3 注意点- Java只允许单继承。 - Java中除了object类之外,每一个类都有一个直接的父类。object类是Java语言的根类。 - 写一个类的时候没有表明这个类继承哪个类的话,这个类默认会继承object类。 - 父类的构造器,子类不能继承。因为构造器必须和当前的类名相同。### 6.8.4 子类继承父类中的哪些成员?这得根据父类成员的访问权限修饰符来判断。父类的构造器,子类不能继承。因为构造器必须和当前的类名相同。### 6.8.5 覆盖继承的字段只要字段名相同即刻。### 6.8.6 覆盖继承的方法原则:- 方法名+方法的参数列表必须相同 - 子类方法的返回值类型是和父类方法的返回类型相同或者是其子类。 - 子类方法声明抛出的异常类型和父类方法声明抛出的异常类型相同或者是其子类。子类方法可以同时声明抛出多个属于父类方法声明跑出异常类的子类(RuntimeException类型除外)。 - 子类方法的访问权限比父类方法访问权限更大或相等。private修饰的方法不能被子类所继承,也就不存在覆盖的概念。判断是否是覆写方法的必杀技:@override标签,若方法是覆写的方法,在方法前或上贴上该标签,编译通过,否则,编译出错。### 6.8.7 super关键字#### 6.8.7.1 概述当前对象的父类对象。#### 6.8.7.2 使用场景1. 可以使用super解决子类隐藏了父类的字段情况,该情况我们一般不讨论,因为破坏封装。 2. 在子类方法中,调用父类被覆盖的方法,此时使用super。 3. 在子类构造器中,调用父类构造器,此时使用super语句(不写super调用父类构造器的话,默认会调用父类无参数构造器)。 4. 不能和static关键字一起使用。### 6.8.8 子类初始化过程- 在创建子类对象之前,会先创建父类对象。 - 调用子类构造器之前,在子类构造器中会先调用父类的构造器,默认调用的是父类无参数构造器。- 如果父类不存在可以被子类访问的构造器,则不能存在子类。- 如果父类没有提供无参数构造器,此时子类必须显示通过super语句去调用父类带参数的构造器。## 6.9 Object类### 6.9.1 概述Object类是Java语言的根类,要么是一个雷的直接父类,要么就是一个类的间接父类。### 6.9.2 方法#### 6.9.2.1 clone#### 6.9.2.2 equals`public boolean equals(Object obj)`拿当前对象(this)和参数(obj)做比较。在Object类中的equals方法,本身和 “==” 符号相同,都是比较对象的内存地址。官方建议:每个类都应该覆盖equals方法,不要比较内存地址,而去比较我们关心的数据。因为我们关心的是内容数据,而不是内存地址。#### 6.9.2.3 finalize`protected void finalize() throws Throwable`当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。垃圾回收器在回收某一个对象之前,会先调用该方法,做扫尾操作,该方法我们不要去调用。#### 6.9.2.4 getClass`public final Class<?> getClass()`返回当前对象的真实类型。```java public class test{public static void main(String[] args) {dog a=new smalldog();System.out.println(a.getClass());System.out.println(smalldog.class);String str1="字符串1";Object str2="字符串2";System.out.println(str1.getClass());System.out.println(str2.getClass());System.out.println(String.class);System.out.println(str2.getClass() == String.class);} }class animal{} class dog extends animal{} class smalldog extends dog{} ```#### 6.9.2.5 hashCode`public int hashCode()`返回该对象的哈希码值,hashCode决定了对象在哈希表中的存储位置,不用对象的hashCode是不一样的。#### 6.9.2.6 notify#### 6.9.2.7 notifyAll#### 6.9.2.8 toString`public String toString()`表示把一个对象转换为字符串。打印对象时,其实打印的就是对象的toString方法。System.out.println(obj对象); 等价于 System.out.println(obj对象.toString());默认情况下打印对象,打印的是对象的十六进制的hashCode值,但是我么更关心对象中存储的数据。官方建议:每个类都应该覆盖toString方法,返回我们关心的数据。#### 6.9.2.9 wait## 6.10 多态### 6.10.1 概述`Animal a = new Dog();`对象a具有2种类型。- 编译类型:声明对象变量的类型,Animal表示把对象看出什么类型。 - 运行类型:对象的真实类型,Dog。### 6.10.2 注意点- 编译类型必须是运行类型的父类或相同。 - 多态的前提:可以是继承关系(类和类),也可以是实现关系(接口和实现类),在开发中多态一般都指第二种。### 6.10.3 特点把子类对象赋给父类变量,在运行时期会表现出具体的子类特征。### 6.10.4 代码```java public class test {public static void main(String[] args) {Person p=new Person();Dog d=new Dog();p.feed(d);} }class Animal{public static void dowork(){System.out.println("animal dowork");}public void eat(){System.out.println("动物吃东西");} }class Dog extends Animal{public static void dowork(){System.out.println("dog dowork");}public void eat(){System.out.println("狗吃东西");}}class Person{public void feed(Animal a){a.eat(); //把 Dog d 传进来,此时编译类型是Animal,运行类型是Dog } } ```以上代码中:`编译类型是Animal,运行类型是Dog`- animal没有eat(),dog有eat(),会报错。原因:编译时Animal类没有eat()。 - animal有eat(),dog没有eat(),dog会继承animal的eat()。结果是“动物吃东西”。原因:编译通过,运行时调用dog的eat()。 - animal有eat(),dog有eat(),结果是“狗吃东西”。原因:编译通过,运行时调用dog的eat()。 - `Animal a=new Dog()`,此时a.dowork()的话,结果是“animal dowork”。原因:静态方法的调用只需要类即可。如果使用对象来调用静态方法,其实是用对象的编译类型来调用静态方法,和对象没有关系。# 7 包## 7.1 概述把多个Java文件,存储在多个目录中,把这个目录称之为包。## 7.2 语法格式`package 包名.子包名.子包名;`必须把该语句作为Java文件中第一行代码。## 7.3 如何定义?1. 包名必须准寻标识符规范/全部小写。 2. 企业开发中,包名采用公司域名倒写。 3. 在开发中,都是先有package而后在package中再定义类。## 7.4 JDK中的包名| 包名 | 描述 | | ---------- | -------------------------------------------------- | | java.lang | 语言核心类,系统自动导入。 | | java.util | Java工具类、集合框架、时间、日历等。 | | java.net | 网络编程接口和类,和网络相关的应用。 | | java.io | 流的接口和类,读写文件或者图片等。 | | java.text | Java格式化相关类,软件国际化需要用这个包。 | | java.sql | jdbc相关接口和类,操作Java连接数据库。 | | java.awt | 抽象窗口工具集相关接口和类,界面应用需要用这个包。 | | java.swing | 图形用户界面相关接口和类(可夸平台)。 |# 8 引入## 8.1 概述当A类和B类不在同一个包中,若A类需要使用到B类,此时就得让A类中去引入B类。## 8.2 操作没有使用import之前,操作不在同一个包中的类,得使用全限定名来操作。```java int[] arr=new int[]{7,5,1}; java.util.Arrays.sort(arr); ```使用import语句,直接把某个包下的类引入到当前类中。此后,在Java文件中,只需要使用类的简单名称即可。```java import java.util.Arrays; . . . int[] arr=new int[]{7,5,1}; Arrays.sort(arr); ```## 8.3 一句话引入多个类使用通配符(*)```java import java.util.*; //自动引入下文中所使用到的类 ```## 8.4 编译器默认引入编译器会默认找java.lang包下的类。但是却不会去找java.lang的子包下的类。比如:java.lang.reflect.Method类。此时我们也得使用:import java.lang.reflect.Method## 8.5 静态引入普通的引入只能引入某个包下的类。```java import java.util.Arrays; . . . int[] arr=new int[]{7,5,1}; Arrays.sort(arr); ```静态引入可以引入某个包下的某个类的静态成员。```java import static java.util.Arrays.sort; . . . int[] arr=new int[]{7,5,1}; sort(arr); ```