标识符与命名规范
标识符
Java 对各种变量、方法和类等要素命名时使用的字符序列称为标识符
技巧:凡是自己可以起名字的地方都叫标识符。
定义合法标识符规则
由26个英文字母大小写,0-9 ,_或$组成
数字不可以开头。
不可以使用关键字和保留字,但能包含关键字和保留字。
Java中严格区分大小写,长度无限制。
标识符不能包含空格。
练习:miles, Test, a++, --a, 4#R, $4, #44, apps, class, public, int, x, y, radius
Java中的名称命名规范
包名
多单词组成时所有字母都小写:xxxyyyzzz
类名、接口名
多单词组成时,所有单词的首字母大写:XxxYyyZzz
变量名、方法名
多单词组成时,第一个单词首字母小写,第二个单词开始每个
单词首字母大写:xxxYyyZzz
常量名
所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
注意1:在起名字时,为了提高阅读性,要尽量有意义,“见名知意”。
注意2:java采用unicode字符集,因此标识符也可以使用汉字声明,但是不建议使用。
使用变量注意事项
Java中每个变量必须先声明,后使用(否则会编译失败)
使用变量名来访问这块区域的数据
变量的作用域:其定义所在的一对{ }内
变量只有在其作用域内才有效
同一个作用域内,不能定义重名的变量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9h5cKvT2-1631633254213)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806223011477.png)]
变量的分类(按数据类型)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qfRqe4m8-1631633254217)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806223440586.png)]
各种变量类型与其表示范围
整数类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fjhQdfkI-1631633254219)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806224402195.png)]
浮点类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h0XyG1eN-1631633254223)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806233006012.png)]
字符类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7Y0IeBmA-1631633254226)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806233809741.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWCkQmEg-1631633254227)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210806235329165.png)]
布尔类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BZM5gFHo-1631633254229)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807003246851.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5J5Uwc2c-1631633254230)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807003827294.png)]
类型转换(整型常量默认为int,浮点型常量默认为double)
自动类型提升
容量小的类型自动转换为容量大的数据类型。
数据类型按容量大小排序为:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jkMgSI8L-1631633254231)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807105500719.png)]
有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
boolean类型不能与其它数据类型运算。
当把任何基本数据类型的值和字符串(String)进行连接运算时(+),基本数据类型的值将自动转化为字符串(String)类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGvD6jwR-1631633254232)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807104645682.png)]
强制类型转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GTIxjMi8-1631633254234)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807105930762.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CkD6AGc8-1631633254235)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807110123009.png)]
String类型
char VS String
char类型初始值不能为空,String类型可以
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xatV54Yh-1631633254237)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807111532248.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nFANGpLn-1631633254238)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807112052894.png)]
判断对错
String str1 = 4; //判断对错:no
进制与进制之间的转换
进制简介
所有数字在计算机底层都以二进制形式存在。
对于整数,有四种表示方式:
二进制(binary):0,1 ,满2进1.以0b或0B开头。
十进制(decimal):0-9 ,满10进1。
八进制(octal):0-7 ,满8进1. 以数字0开头表示。
十六进制(hex):0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。
如:0x21AF +1= 0X21B0
原码反码补码
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;
当是long类型时,二进制默认占64位,第64位是符号位
二进制的整数有如下三种形式:
原码:直接将一个数值换成二进制数。最高位是符号位
负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
负数的补码:其反码加1。
计算机以二进制补码的形式保存所有的整数。
正数的原码、反码、补码都相同
负数的补码是其反码+1
为什么要使用原码、反码、补码表示形式呢
计算机辨别“符号位”显然会让计算机的基础电路设计变得十分复杂! 于是
人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正
数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有
减法, 这样计算机运算的设计就更简单了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OkLp9zpX-1631633254239)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807153816331.png)]
进制之间的转换
十进制 二进制互转
二进制转成十进制
乘以2的幂数
十进制转成二进制
除以2取余数
二进制 八进制互转
二进制 十六进制互转
十进制 八进制互转
十进制 十六进制互转
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yjwIkPut-1631633254241)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807160005119.png)]
运算符
%
结果符号与被求模数符号一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WcVPxTt9-1631633254242)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807161024883.png)]
=
连续赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e4ijl2Ps-1631633254244)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807162215233.png)]
a+=b不一定等于a=a+b
说明+=不会改变本身变量的数据类型与++,–运算符一样
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xfWcrHJd-1631633254245)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807162511388.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vZnBaxNt-1631633254246)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807162500966.png)]
题目一
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D1LVFXW0-1631633254248)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812152013957.png)]
++
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kGB32mbs-1631633254249)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807163032623.png)]
& VS &&
&—逻辑与
| —逻辑或
!—逻辑非
&& —短路与
|| —短路或
^ —逻辑异或
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qonAovDJ-1631633254250)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807163528688.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qGEvY4zO-1631633254251)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807163710050.png)]
<< VS <<<
<<才是乘以2操作
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cp0pNTUC-1631633254252)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807171719389.png)]
?表达式1:表达式2
表达式1和表达式2为同种类型
if-else(就近原则)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GQBtIgse-1631633254253)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807221849193.png)]
题目一
两种写法不一样
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4z7NdVEW-1631633254254)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210817193226382.png)]
switch表达式中的类型
switch(表 达式)中表达式的值必须是下述几种类型之一:
byte,short,char,int,枚举(jdk 5.0),String (jdk 7.0);
case子句中的值必须是常量,不能是变量名或不确定的表达式值(
1.boolean类型不能参与运算
2.不和if-else长得像
);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pIrhD6Ro-1631633254255)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807234410830.png)]
同一个switch语句,所有case子句中的常量值互不相同;
break语句用来在执行完一个case分支后使程序跳出switch语句块;如果没有break,程序会顺序执行到switch结尾;
default子句是可任选的。同时,位置也是灵活的。当没有匹配的case时,执行default
不能为long,double,float,boolean类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEhqrDKs-1631633254256)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807234200206.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6vhIWhCk-1631633254257)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210807234226996.png)]
for循环
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGrjEiCx-1631633254258)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808002244011.png)]
变量初始化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hggSLNFa-1631633254259)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808095614892.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVEgk920-1631633254261)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808095703540.png)]
质数
质数:素数,只能被1和它本身整除的自然数。–>从2开始,到这个数-1结束为止,都不能被这个数本身整除。
最小的质数是:2
算法时间测试
输出也会占用大量时间
break VS continue
使用范围 循环中使用的作用(不同点) 相同点
break: 循环结构中 结束当前循环 关键字后面不能声明执行语句
continue: 循环结构中 结束当次循环 关键字后面不能声明执行语句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sEYlAL7d-1631633254262)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808130632010.png)]
return
return:并非专门用于结束循环的,它的功能是结束一个方法。当一个方法执行到一个return语句时,这个方法将被结束。
与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之内
数组
数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
数组的长度一旦确定,就不能修改。
初始化
一维数组
数组一旦初始化完成,其长度就确定了
int[] ids;//声明
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//错误的写法:
// int[] arr1 = new int[];
// int[5] arr2 = new int[5];
// int[] arr3 = new int[3]{1,2,3};
//也是正确的写法:
int[] arr4 = {1,2,3,4,5};//类型推断
二维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//错误的情况
// String[][] arr4 = new String[][4];
// String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};
默认值
数组元素是整型:0
数组元素是浮点型:0.0
数组元素是char型:0或’\u0000’,而非’0’
数组元素是boolean型:false
数组元素是引用数据类型:null
内存结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kMfuau4q-1631633254263)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808174124694.png)]
一维数组
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IHZOHmdS-1631633254264)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808174422787.png)]
二维数组(本质都是一维数组 )
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gtDzImcz-1631633254265)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808221618348.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sqo9ERlc-1631633254266)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808230411452.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OaineDir-1631633254268)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808230639828.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UcI6qykR-1631633254271)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808230702599.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-11ThQZ6D-1631633254272)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808230715723.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XOnmxyp3-1631633254273)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808231153843.png)]
赋值规则
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MZFbnKOY-1631633254274)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210808233404679.png)]
杨辉三角
package com.wdl.day07;
/**
* @创建人 wdl
* @创建时间 2021/8/8
* @描述
*/
public class YangHuiTest {
public static void main(String[] args) {
int[][] yanghui = new int[10][];
for (int i = 0; i < yanghui.length; i++) {
yanghui[i] = new int[i + 1];
yanghui[i][0] = 1;
yanghui[i][i] = 1;
for (int j = 1; j < i; j++) {
yanghui[i][j] = yanghui[i - 1][j] + yanghui[i - 1][j - 1];
}
}
for (int[] ints : yanghui) {
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
}
}
二分查找
package com.wdl.day07;
/**
* @创建人 wdl
* @创建时间 2021/8/9
* @描述
*/
public class ArrayTest2 {
public static void main(String[] args) {
int[] arr = {-2, -1, 0, 5, 6, 9, 55};
int head=0;
int end=arr.length-1;
int dest1=505;
boolean isFlag=true;
while (head <= end) {
int middle=(head+end)/2;
if (dest1==arr[middle]){
System.out.println("找到了指定的元素,位置为:"+middle);
isFlag=false;
break;
}else if (dest1>arr[middle]){
head = middle+1;
}
if (dest1<arr[middle]){
end=middle-1;
}
}
if (isFlag){
System.out.println("很遗憾,没有找到的啦!");
}
}
}
冒泡排序
package com.wdl.day07;
import java.util.Arrays;
/**
* @创建人 wdl
* @创建时间 2021/8/9
* @描述
*/
public class BubbleSortTest {
public static void main(String[] args) {
int[] arr = {4, 0, 2, 5, 4, 8, 7, 8, -2, -9, 66};
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
类的成员组成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fynWYFM3-1631633254275)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210809233842204.png)]
对象的创建和使用(内存解析)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M9eXqKJv-1631633254275)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210810152553749.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJODZXtw-1631633254276)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210810153310042.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhfATAVt-1631633254277)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210811163349777.png)]
属性VS局部变量
类中属性的使用
属性(成员变量) vs 局部变量
1.相同点:
1.1 定义变量的格式:数据类型 变量名 = 变量值
1.2 先声明,后使用
1.3 变量都有其对应的作用域
2.不同点:
2.1 在类中声明的位置的不同
属性:直接定义在类的一对{}内
局部变量:声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量
2.2 关于权限修饰符的不同
属性:可以在声明属性时,指明其权限,使用权限修饰符。
常用的权限修饰符:private、public、缺省、protected --->封装性
目前,大家声明属性时,都使用缺省就可以了。
局部变量:不可以使用权限修饰符。
2.3 默认初始化值的情况:
属性:类的属性,根据其类型,都有默认初始化值。
整型(byte、short、int、long):0
浮点型(float、double):0.0
字符型(char):0 (或'\u0000')
布尔型(boolean):false
引用数据类型(类、数组、接口):null
局部变量:没有默认初始化值。
意味着,我们在调用局部变量之前,一定要显式赋值。
特别地:形参在调用时,我们赋值即可。
2.4 在内存中加载的位置:
属性:加载到堆空间中 (非static)
局部变量:加载到栈空间
类中的方法
方法的使用中,可以调用当前类的属性或方法
-
特殊的:方法A中又调用了方法A:递归方法。
-
方法中,不可以定义方法。
方法的调用
public class Exer3Test {
public static void main(String[] args) {
Exer3Test test = new Exer3Test();
//3.1测试
// test.method();
//3.2测试
//方式一:
// int area = test.method();
// System.out.println("面积为:" + area);
//方式二:
// System.out.println(test.method());
//3.3测试
int area = test.method(12, 10);
System.out.println("面积为:" + area);
}
//3.1
// public void method(){
// for(int i = 0;i < 10;i++){
// for(int j = 0;j < 8;j++){
// System.out.print("* ");
// }
// System.out.println();
// }
// }
//3.2
// public int method(){
// for(int i = 0;i < 10;i++){
// for(int j = 0;j < 8;j++){
// System.out.print("* ");
// }
// System.out.println();
// }
//
// return 10 * 8;
// }
//3.3
public int method(int m,int n){
for(int i = 0;i < m;i++){
for(int j = 0;j < n;j++){
System.out.print("* ");
}
System.out.println();
}
return m * n;
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eHxmTl3Y-1631633254279)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210810171412771.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p9aBEHVk-1631633254280)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210810171356591.png)]
交换两个对象
//问题二:使用冒泡排序按学生成绩排序,并遍历所有学生信息
for(int i = 0;i < stus.length - 1;i++){
for(int j = 0;j < stus.length - 1 - i;j++){
if(stus[j].score > stus[j + 1].score){
//如果需要换序,交换的是数组的元素:Student对象!!!
Student temp = stus[j];
stus[j] = stus[j + 1];
stus[j + 1] = temp;
}
}
}
面向对象VS面向过程
1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎样做。
2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。
变量的分类(按照在类中声明的位置)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BhKTKXVA-1631633254281)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210811150505941.png)]
理解“万物皆对象”
一、理解“万事万物皆对象”
1.在Java语言范畴中,我们都将功能、结构等封装到类中,通过类的实例化,来调用具体的功能结构
>Scanner,String等
>文件:File
>网络资源:URL
2.涉及到Java语言与前端Html、后端的数据库交互时,前后端的结构在Java层面交互时,都体现为类、对象。
匿名对象
匿名对象的使用
- 1.理解:我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
- 2.特征:匿名对象只能调用一次。
- 3.使用:如下
package com.wdl.day09;
/*
* 匿名对象的使用
* 1.理解:我们创建的对象,没有显式的赋给一个变量名。即为匿名对象
* 2.特征:匿名对象只能调用一次。
* 3.使用:如下
*
*/
public class InstanceTest {
public static void main(String[] args) {
Phone p = new Phone();
// p = null;
System.out.println(p);
p.sendEmail();
p.playGame();
//匿名对象
// new Phone().sendEmail();
// new Phone().playGame();
new Phone().price = 1999;
new Phone().showPrice();//0.0
//**********************************
PhoneMall mall = new PhoneMall();
// mall.show(p);
//匿名对象的使用
mall.show(new Phone());
}
}
class PhoneMall{
public void show(Phone phone){
phone.sendEmail();
phone.playGame();
}
}
class Phone{
double price;//价格
public void sendEmail(){
System.out.println("发送邮件");
}
public void playGame(){
System.out.println("玩游戏");
}
public void showPrice(){
System.out.println("手机价格为:" + price);
}
}
方法的重载
package com.wdl.day09;
/*
* 方法的重载(overload) loading...
*
* 1.定义:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
*
* "两同一不同":同一个类、相同方法名
* 参数列表不同:参数个数不同,参数类型不同
*
* 2. 举例:
* Arrays类中重载的sort() / binarySearch()
*
* 3.判断是否是重载:
* 跟方法的权限修饰符、返回值类型、形参变量名、方法体都没有关系!
*
* 4. 在通过对象调用方法时,如何确定某一个指定的方法:
* 方法名 ---> 参数列表
*/
public class OverLoadTest {
public static void main(String[] args) {
OverLoadTest test = new OverLoadTest();
test.getSum(1,2);
}
//如下的4个方法构成了重载
public void getSum(int i,int j){
System.out.println("1");
}
public void getSum(double d1,double d2){
System.out.println("2");
}
public void getSum(String s ,int i){
System.out.println("3");
}
public void getSum(int i,String s){
System.out.println("4");
}
//如下的3个方法不能与上述4个方法构成重载
// public int getSum(int i,int j){
// return 0;
// }
// public void getSum(int m,int n){
//
// }
// private void getSum(int i,int j){
//
// }
}
可变个数的形参
package com.wdl.day09;
/*
* 可变个数形参的方法
*
* 1.jdk 5.0新增的内容
* 2.具体使用:
* 2.1 可变个数形参的格式:数据类型 ... 变量名
* 2.2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
* 2.3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
* 2.4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
* 2.5 可变个数形参在方法的形参中,必须声明在末尾
* 2.6 可变个数形参在方法的形参中,最多只能声明一个可变形参。
*
*/
public class MethodArgsTest {
public static void main(String[] args) {
MethodArgsTest test = new MethodArgsTest();
test.show(12);
// test.show("hello");
// test.show("hello","world");
// test.show();
test.show(new String[]{"AA","BB","CC"});
}
public void show(int i){
}
public void show(String s){
System.out.println("show(String)");
}
public void show(String ... strs){
System.out.println("show(String ... strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}
// //不能与上一个方法同时存在
// public void show(String[] strs){
//
// }
//The variable argument type String of the method
//show must be the last parameter
// public void show(String ...strs,int i){
//
// }
}
方法参数的值传递机制
形参是基本数据类型:将实参基本数据类型变量的**“数据值”**传递给形参
形参是引用数据类型:将实参引用数据类型变量的**“地址值”**传递给形参
基本数据类型
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COn673p1-1631633254282)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210811221501431.png)]
引用数据类型(对象中)
public static void main(String[] args) {
Person obj = new Person();
obj.age = 5;
System.out.println("修改之前age = " + obj.age);// 5
// x是实参
change(obj);
System.out.println("修改之后age = " + obj.age);// 5
}
public static void change(Person obj) {
obj = new Person();
System.out.println("change:修改之前age = " + obj.age);
obj.age = 3;
System.out.println("change:修改之后age = " + obj.age);
}
其中Person类定义为:
class Person {
int age;
}
错误交换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ks3yDG8O-1631633254283)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210811223841293.png)]
正确的交换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pxpleaSQ-1631633254285)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210811225434360.png)]
探索几道网红题
题目一
package com.wdl.day09;
public class Method {
public static void main(String args[]) {
Method test = new Method();
test.first();
}
public void first() {
int i = 5;
Value v = new Value();
v.i = 25;
second(v, i);
System.out.println("first"+v.i);
}
public void second(Value v, int i) {
i = 0;
v.i = 20;
Value val = new Value();
v = val;
System.out.println("second"+v.i + " " + i);
}
}
class Value {
int i = 15;
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dXwidwW6-1631633254286)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812102918990.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VlGA2U7x-1631633254287)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812102855149.png)]
题目二
package com.wdl.day09;
/**
* @创建人 wdl
* @创建时间 2021/8/12
* @描述
*/
public class ArrayPrintTest {
public static void main(String[] args) {
int[] arr =new int[]{1, 2, 3};
System.out.println(arr);//地址值
char[] arr1 = {'a', 'b','c'};
System.out.println(arr1);//abc
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7FVSUPe4-1631633254288)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812104158193.png)]
原因
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IryXFg7O-1631633254289)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812103922123.png)]
题目三
相当于又new了一个对象
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xfuVZWzH-1631633254290)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812163448096.png)]
递归
题目一
递归总要不断的向终止条件靠近
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDPfUPsK-1631633254292)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812111257922.png)]
题目二
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VzWeT8wI-1631633254293)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812163935523.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FG6ot1Hv-1631633254294)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812163919321.png)]
封装性
体现一
Java中通过将属性声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作,以实现下述目的:
隐藏一个类中不需要对外提供的实现细节;
使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
便于修改,增强代码的可维护性;
体现二
不对外暴露的私有方法
体现三
单例模式(将构造器私有化)
体现四
如果不希望类在包外被调用,可以将类设置为缺省的。
权限修饰符
封装性的体现,需要权限修饰符来配合。
1.Java规定的4种权限(从小到大排列):private、缺省、protected 、public
2. 4种权限可以用来修饰类及类的内部结构:属性、方法、构造器、内部类
3.具体的,4种权限都可以用来修饰类的内部结构:属性、方法、构造器、内部类
修饰类的话,只能使用:缺省、public
总结封装性:Java提供了4种权限修饰符来修饰类及类的内部结构,体现类及类的内部结构在被调用时的可见性的大小。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fhKIVU31-1631633254295)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812165925156.png)]
构造器
一、构造器的作用:
1.创建对象
2.初始化对象的信息
二、说明:
1.如果没有显式的定义类的构造器的话,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
5.一个类中,至少会有一个构造器。
JavaBean
JavaBean是一种Java语言写成的可重用组件。
所谓javaBean,是指符合如下标准的Java类:
类是公共的
有一个无参的公共的构造器
有属性,且有对应的get、set方法
用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以
用Java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP
页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用
户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关
心任何改变
2wh
what why how
this关键字
this关键字的使用:
1.this可以用来修饰、调用:属性、方法、构造器
2.this修饰属性和方法:
this理解为:当前对象 或 当前正在创建的对象
2.1 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对
通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们
的使用"this.变量"的方式,表明此变量是属性,而非形参。
2.2 在类的构造器中,我们可以使用"this.属性"或"this.方法"的方式,调用当前正
但是,通常情况下,我们都选择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时
的使用"this.变量"的方式,表明此变量是属性,而非形参。
3. this调用构造器
① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他
② 构造器中不能通过"this(形参列表)"方式调用自己
③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)"
④ 规定:"this(形参列表)"必须声明在当前构造器的首行
⑤ 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(1);
System.out.println(p1.getAge());
p1.eat();
System.out.println();
Person p2 = new Person("Jerry",20);
System.out.println(p2.getAge());
}
}
class Person{
private String name;
private int age;
public Person(){
// this.eat();
String info = "Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)";
System.out.println(info);
}
public Person(String name){
this();
this.name = name;
}
public Person(int age){
this();
this.age = age;
}
public Person(String name,int age){
this(age);
this.name = name;
//this.age = age;
//Person初始化时,需要考虑如下的1,2,3,4...(共40行代码)
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void eat(){
System.out.println("人吃饭");
this.study();
}
public void study(){
System.out.println("人学习");
}
}
对象数组
错误一(没有初始化)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uhczG5ft-1631633254296)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812224132218.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WWCEEHUy-1631633254297)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812224148673.png)]
正确写法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qbJ6O5TQ-1631633254298)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210812224317925.png)]
import关键字
-
在源文件中显式的使用import结构导入指定包下的类、接口
-
声明在包的声明和类的声明之间
-
如果需要导入多个结构,则并列写出即可
-
可以使用"xxx.*"的方式,表示可以导入xxx包下的所有结构
-
如果使用的类或接口是java.lang包下定义的,则可以省略import结构
-
如果使用的类或接口是本包下定义的,则可以省略import结构
-
如果在源文件中,使用了不同包下的同名的类,则必须至少有一个类需要以全类名的方式显示。
-
使用"xxx.*"方式表明可以调用xxx包下的所有结构。但是如果使用的是xxx子包下的结构,则仍需要显式导入
-
import static:导入指定类或接口中的静态结构:属性或方法。
package com.atguigu.java2;
import java.lang.reflect.Field;
import java.util.*;
import com.atguigu.exer4.Account;
import com.atguigu.exer4.Bank;
import com.atguigu.java2.java3.Dog;
import static java.lang.System.*;
import static java.lang.Math.*;
public class PackageImportTest {
public static void main(String[] args) {
String info = Arrays.toString(new int[]{1,2,3});
Bank bank = new Bank();
ArrayList list = new ArrayList();
HashMap map = new HashMap();
Scanner s = null;
System.out.println("hello!");
Person p = new Person();
Account acct = new Account(1000);
//全类名的方式显示
com.atguigu.exer3.Account acct1 = new com.atguigu.exer3.Account(1000,2000,0.0123);
Date date = new Date();
java.sql.Date date1 = new java.sql.Date(5243523532535L);
Dog dog = new Dog();
Field field = null;
out.println("hello");
long num = round(123.434);
}
}
项目二内存分析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HQHML5rm-1631633254299)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210813162354263.png)]
继承性
一、继承性的好处:
① 减少了代码的冗余,提高了代码的复用性
② 便于功能的扩展
③ 为之后多态性的使用,提供了前提
二、继承性的格式:
class A extends B{}
A:子类、派生类、subclass
B:父类、超类、基类、superclass
2.1体现:一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。
特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。
只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
2.2 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。
子类和父类的关系,不同于子集和集合的关系。
extends:延展、扩展
三、Java中关于继承性的规定:
1.一个类可以被多个子类继承。
2.Java中类的单继承性:一个类只能有一个父类
3.子父类是相对的概念。
4.子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
5.子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
四、 1. 如果我们没有显式的声明一个类的父类的话,则此类继承于java.lang.Object类
2. 所有的java类(除java.lang.Object类之外)都直接或间接的继承于java.lang.Object类
3. 意味着,所有的java类具有java.lang.Object类声明的功能。
重写
方法的重写(override / overwrite)
1.重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作
2.应用:重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。
3. 重写的规定:
方法的声明: 权限修饰符 返回值类型 方法名(形参列表) throws 异常的类型{
//方法体
}
约定俗称:子类中的叫重写的方法,父类中的叫被重写的方法
① 子类重写的方法的方法名和形参列表与父类被重写的方法的方法名和形参列表相同
② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符
>特殊情况:子类不能重写父类中声明为private权限的方法
③ 返回值类型:
>父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
>父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类
>父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
④ 子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)
**********************************************************************
子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。
形参列表必须一致
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rx59EyZr-1631633254300)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814003720986.png)]
题目一
编译看左边,运行看右边
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x9o8jhLJ-1631633254301)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814180553979.png)]
有可变的参数列表和不可变的参数列表,优先调用不可变的参数列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0XB2zPWa-1631633254302)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814180653041.png)]
super关键字
super关键字的使用
1.super理解为:父类的
2.super可以用来调用:属性、方法、构造器
3.super的使用:调用属性和方法
3.1 我们可以在子类的方法或构造器中。通过使用"super.属性"或"super.方法"的方式,显式的调用
父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super."
3.2 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的
使用"super.属性"的方式,表明调用的是父类中声明的属性。
3.3 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的
使用"super.方法"的方式,表明调用的是父类中被重写的方法。
4.super调用构造器
4.1 我们可以在子类的构造器中显式的使用"super(形参列表)"的方式,调用父类中声明的指定的构造器
4.2 "super(形参列表)"的使用,必须声明在子类构造器的首行!
4.3 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)“只能二选一,不能同时出现
4.4 在构造器的首行,没有显式的声明"this(形参列表)“或"super(形参列表)”,则默认调用的是父类中空参的构造器:super()
4.5 在类的多个构造器中,至少有一个类的构造器中使用了"super(形参列表)”,调用父类中的构造器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XHm57SpN-1631633254303)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814132845483.png)]
子类对象实例化的全过程
1. 从结果上来看:(继承性)
子类继承父类以后,就获取了父类中声明的属性或方法。
创建子类的对象,在堆空间中,就会加载所有父类中声明的属性。
2. 从过程上来看:
当我们通过子类的构造器创建子类对象时,我们一定会直接或间接的调用其父类的构造器,进而调用父类的父类的构造器,...
直到调用了java.lang.Object类中空参的构造器为止。正因为加载过所有的父类的结构,所以才可以看到内存中有
父类中的结构,子类对象才可以考虑进行调用。
明确:虽然创建子类对象时,调用了父类的构造器,但是自始至终就创建过一个对象,即为new的子类对象。
多态性
多态性只适用于方法,不适用于属性
1.若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里的同名方法,系统将不可能把父类里的方法转移到子类中:编译看左边,运行看右边
2.对于实例变量则不存在这样的现象,即使子类里定义了与父类完全相同的实例变量,这个实例变量依然不可能覆盖父类中定义的实例变量:编译运行都看左边
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vVPhZwX5-1631633254304)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814171459958.png)]
1.理解多态性:可以理解为一个事物的多种形态。
2.何为多态性:
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
3.多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
总结:编译,看左边;运行,看右边。
4.多态性的使用前提: ① 类的继承关系 ② 方法的重写
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lONAgHxX-1631633254305)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814150424371.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kM13r653-1631633254306)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814165711245.png)]
调用子类特有的属性和方法(强制类型转换)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rqnfR59B-1631633254307)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814165829408.png)]
注意事项:
先判断对象a是否是类A的实例
题目一
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-De4vbAUB-1631633254308)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815141043218.png)]
题目二
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sKB19FGl-1631633254309)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210901145353698.png)]
instanceof关键字
instanceof关键字的使用
a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false。
使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先
进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,不进行向下转型。
如果 a instanceof A返回true,则 a instanceof B也返回true.
其中,类B是类A的父类。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8hetTZ5y-1631633254309)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210814170058517.png)]
举例
//练习:
//问题一:编译时通过,运行时不通过
//举例一:
// Person p3 = new Woman();
// Man m3 = (Man)p3;
//举例二:
// Person p4 = new Person();
// Man m4 = (Man)p4;
//问题二:编译通过,运行时也通过
// Object obj = new Woman();
// Person p = (Person)obj;
//问题三:编译不通过
// Man m5 = new Woman();
// String str = new Date();
// Object o = new Date();
// String str1 = (String)o;
Object类
java.lang.Object类
1.Object类是所有Java类的根父类
2.如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
3.Object类中的功能(属性、方法)就具有通用性。
属性:无
方法:equals() / toString() / getClass() /hashCode() / clone() / finalize()
wait() 、 notify()、notifyAll()
- Object类只声明了一个空参的构造器
面试题:
final、finally、finalize的区别?
== 和 equals() 区别
一、回顾 == 的使用:
== :运算符
1. 可以使用在基本数据类型变量和引用数据类型变量中
2. 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)
如果比较的是引用数据类型变量:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
补充: **== 符号使用时,必须保证符号左右两边的变量类型一致。**
二、equals()方法的使用:
1. 是一个方法,而非运算符
2. 只能适用于引用数据类型
3. Object类中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
4. 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是
两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
5. 通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们
就需要对Object类中的equals()进行重写.
重写的原则:比较两个对象的实体内容是否相同.
package com.wdl.day13;
import java.util.Date;
public class EqualsTest {
public static void main(String[] args) {
//基本数据类型
int i = 10;
int j = 10;
double d = 10.0;
System.out.println(i == j);//true
System.out.println(i == d);//true
boolean b = true;
// System.out.println(i == b);
char c = 10;
System.out.println(i == c);//true
char c1 = 'A';
char c2 = 65;
System.out.println(c1 == c2);//true
//引用类型:
Customer cust1 = new Customer("Tom",21);
Customer cust2 = new Customer("Tom",21);
System.out.println(cust1 == cust2);//false
String str1 = new String("atguigu");
String str2 = new String("atguigu");
System.out.println(str1 == str2);//false
System.out.println("****************************");
System.out.println(cust1.equals(cust2));//false--->true
System.out.println(str1.equals(str2));//true
Date date1 = new Date(32432525324L);
Date date2 = new Date(32432525324L);
System.out.println(date1.equals(date2));//true
}
}
注意事项:
空指针
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNlQCZgJ-1631633254310)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815110445691.png)]
题目一
String存放在常量池中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YRvearG7-1631633254312)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815111759486.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHUgzgVD-1631633254313)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815111249169.png)]
toString()
Object类中toString()的使用:
1. **当我们输出一个对象的引用时,实际上就是调用当前对象的toString()**
2. Object类中toString()的定义:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
3. 像String、Date、File、包装类等都重写了Object类中的toString()方法。
使得在调用对象的toString()时,返回"实体内容"信息
4. 自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"
package com.wdl.day13;
import java.util.Date;
public class ToStringTest {
public static void main(String[] args) {
Customer cust1 = new Customer("Tom",21);
System.out.println(cust1.toString());//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
System.out.println(cust1);//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
String str = new String("MM");
System.out.println(str);//MM
Date date = new Date(4534534534543L);
System.out.println(date.toString());//Mon Sep 11 08:55:34 GMT+08:00 2113
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-raEMolOT-1631633254314)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815112625000.png)]
题目一
当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
但是底层有保护机制,当此参数为null时,直接进行输出
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DP77moYn-1631633254315)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815152028279.png)]
JUnit单元测试
1.选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步
2.创建Java类,进行单元测试。
此时的Java类要求:① 此类是public的 ②此类提供公共的无参的构造器
3.此类中声明单元测试方法。
此时的单元测试方法:方法的权限是public,没有返回值,没有形参
4.此单元测试方法上需要声明注解:@Test,并在单元测试类中导入:import org.junit.Test;
5.声明好单元测试方法以后,就可以在方法体内测试相关的代码。
6.写完代码以后,左键双击单元测试方法名,右键:run as - JUnit Test
说明:
1.如果执行结果没有任何异常:绿条
2.如果执行结果出现异常:红条
package com.wdl.day13;
import java.util.Date;
import org.junit.Test;
public class JUnitTest {
int num = 10;
@Test
public void testEquals(){
String s1 = "MM";
String s2 = "MM";
System.out.println(s1.equals(s2));
//ClassCastException的异常
// Object obj = new String("GG");
// Date date = (Date)obj;
System.out.println(num);
show();
}
public void show(){
num = 20;
System.out.println("show()....");
}
@Test
public void testToString(){
String s2 = "MM";
System.out.println(s2.toString());
}
}
包装类(Wrapper)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dCdI1SWw-1631633254316)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815114441101.png)]
基本数据类型、包装类、String三者之间的相互转换
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WR02rmtq-1631633254317)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815124847192.png)]
package com.wdl.day13;
import org.junit.Test;
/*
* 包装类的使用:
* 1.java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征
*
* 2.掌握的:基本数据类型、包装类、String三者之间的相互转换
*
*
*
*/
public class WrapperTest {
//String类型 --->基本数据类型、包装类:调用包装类的parseXxx(String s)
@Test
public void test5(){
String str1 = "123";
//错误的情况:
// int num1 = (int)str1;
// Integer in1 = (Integer)str1;
//可能会报NumberFormatException
int num2 = Integer.parseInt(str1);
System.out.println(num2 + 1);
String str2 = "true1";
boolean b1 = Boolean.parseBoolean(str2);
System.out.println(b1);
}
//基本数据类型、包装类--->String类型:调用String重载的valueOf(Xxx xxx)
@Test
public void test4(){
int num1 = 10;
//方式1:连接运算
String str1 = num1 + "";
//方式2:调用String的valueOf(Xxx xxx)
float f1 = 12.3f;
String str2 = String.valueOf(f1);//"12.3"
Double d1 = new Double(12.4);
String str3 = String.valueOf(d1);
System.out.println(str2);
System.out.println(str3);//"12.4"
}
/*
* JDK 5.0 新特性:自动装箱 与自动拆箱
*/
@Test
public void test3(){
// int num1 = 10;
// //基本数据类型-->包装类的对象
// method(num1);
//自动装箱:基本数据类型 --->包装类
int num2 = 10;
Integer in1 = num2;//自动装箱
boolean b1 = true;
Boolean b2 = b1;//自动装箱
//自动拆箱:包装类--->基本数据类型
System.out.println(in1.toString());
int num3 = in1;//自动拆箱
}
public void method(Object obj){
System.out.println(obj);
}
//包装类--->基本数据类型:调用包装类Xxx的xxxValue()
@Test
public void test2(){
Integer in1 = new Integer(12);
int i1 = in1.intValue();
System.out.println(i1 + 1);
Float f1 = new Float(12.3);
float f2 = f1.floatValue();
System.out.println(f2 + 1);
}
//基本数据类型 --->包装类:调用包装类的构造器
@Test
public void test1(){
int num1 = 10;
// System.out.println(num1.toString());
Integer in1 = new Integer(num1);
System.out.println(in1.toString());
Integer in2 = new Integer("123");
System.out.println(in2.toString());
//报异常
// Integer in3 = new Integer("123abc");
// System.out.println(in3.toString());
Float f1 = new Float(12.3f);
Float f2 = new Float("12.3");
System.out.println(f1);
System.out.println(f2);
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean("TrUe");
System.out.println(b2);
Boolean b3 = new Boolean("true123");
System.out.println(b3);//false
Order order = new Order();
System.out.println(order.isMale);//false
System.out.println(order.isFemale);//null
}
}
class Order{
boolean isMale;
Boolean isFemale;
}
题目一
类型提升(三元运算符:两边的类型一致)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FIcs7nn6-1631633254319)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815132657172.png)]
题目二
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DrvSHvnH-1631633254320)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815133259897.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uWCtkLQb-1631633254321)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815133058874.png)]
Vector类
数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。而向量类java.util.Vector可以根据需要动态伸缩。
创建Vector对象:Vector v=new Vector();
给向量添加元素:v.addElement(Object obj); //obj必须是对象
取出向量中的元素:Object obj=v.elementAt(0);
注意第一个元素的下标是0,返回值是Object类型的。
计算向量的长度:v.size();
package com.atguigu.exer4;
import java.util.Scanner;
import java.util.Vector;
/*
* 利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
若与最高分相差10分内:A等;20分内:B等;
30分内:C等;其它:D等
*
*
*
*
*/
public class ScoreTest {
public static void main(String[] args) {
//1.实例化Scanner,用于从键盘获取学生成绩
Scanner scan = new Scanner(System.in);
//2.创建Vector对象:Vector v=new Vector();相当于原来的数组
Vector v = new Vector();
//3.通过for(;;)或while(true)方式,给Vector中添加数组
int maxScore = 0;
for(;;){
System.out.println("请输入学生成绩(以负数代表输入结束)");
int score = scan.nextInt();
//3.2 当输入是负数时,跳出循环
if(score < 0){
break;
}
if(score > 100){
System.out.println("输入的数据非法,请重新输入");
continue;
}
//3.1 添加操作::v.addElement(Object obj)
//jdk5.0之前:
// Integer inScore = new Integer(score);
// v.addElement(inScore);//多态
//jdk5.0之后:
v.addElement(score);//自动装箱
//4.获取学生成绩的最大值
if(maxScore < score){
maxScore = score;
}
}
//5.遍历Vector,得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
char level;
for(int i = 0;i < v.size();i++){
Object obj = v.elementAt(i);
//jdk 5.0之前:
// Integer inScore = (Integer)obj;
// int score = inScore.intValue();
//jdk 5.0之后:
int score = (int)obj;
if(maxScore - score <= 10){
level = 'A';
}else if(maxScore - score <= 20){
level = 'B';
}else if(maxScore - score <= 30){
level = 'C';
}else{
level = 'D';
}
System.out.println("student-" + i + " score is " + score + ",level is " + level);
}
}
}
static关键字
1.static:静态的
2.static可以用来修饰:属性、方法、代码块、内部类
3.使用static修饰属性:静态变量(或类变量)
3.1 属性,按是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)
实例变量:我们创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的
非静态属性时,不会导致其他对象中同样的属性值的修改。
静态变量:我们创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致
其他对象调用此静态变量时,是修改过了的。
3.2 static修饰属性的其他说明:
① 静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用
② 静态变量的加载要早于对象的创建。
③ 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
④ 类变量 实例变量
类 yes no
对象 yes yes
3.3 静态属性举例:System.out; Math.PI;
4.使用static修饰方法:静态方法
① 随着类的加载而加载,可以通过"类.静态方法"的方式进行调用
② 静态方法 非静态方法
类 yes no
对象 yes yes
③ 静态方法中,只能调用静态的方法或属性
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
5. static注意点:
5.1 在静态的方法内,不能使用this关键字、super关键字
5.2 关于静态属性和静态方法的使用,大家都从生命周期的角度去理解。
6. 开发中,如何确定一个属性是否要声明为static的?
> 属性是可以被多个对象所共享的,不会随着对象的不同而不同的。
> 类中的常量也常常声明为static
开发中,如何确定一个方法是否要声明为static的?
> 操作静态属性的方法,通常设置为static的
> 工具类中的方法,习惯上声明为static的。 比如:Math、Arrays、Collections
package com.wdl.day14;
public class StaticTest {
public static void main(String[] args) {
Chinese.nation = "中国";
Chinese c1 = new Chinese();
c1.name = "姚明";
c1.age = 40;
c1.nation = "CHN";
Chinese c2 = new Chinese();
c2.name = "马龙";
c2.age = 30;
c2.nation = "CHINA";
System.out.println(c1.nation);
//编译不通过
// Chinese.name = "张继科";
c1.eat();
Chinese.show();
//编译不通过
// Chinese.eat();
// Chinese.info();
}
}
//中国人
class Chinese{
String name;
int age;
static String nation;
public void eat(){
System.out.println("中国人吃中餐");
//调用非静态结构
this.info();
System.out.println("name :" +name);
//调用静态结构
walk();
System.out.println("nation : " + nation);
}
public static void show(){
System.out.println("我是一个中国人!");
//不能调用非静态的结构
// eat();
// name = "Tom";
//可以调用静态的结构
System.out.println(Chinese.nation);
walk();
}
public void info(){
System.out.println("name :" + name +",age : " + age);
}
public static void walk(){
}
}
类变量VS实例变量内存解析
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1QfCMi6f-1631633254322)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815181710632.png)]
单例 (Singleton)设计模式
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。
1. 所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例。
2. 如何实现?
饿汉式 vs 懒汉式
3. 区分饿汉式 和 懒汉式
饿汉式:
坏处:对象加载时间过长。
好处:饿汉式是线程安全的
懒汉式:
好处:延迟对象的创建。
目前的写法坏处:线程不安全。--->到多线程内容时,再修改
饿汉式
package com.wdl.day14;
public class SingletonTest1 {
public static void main(String[] args) {
// Bank bank1 = new Bank();
// Bank bank2 = new Bank();
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2);
}
}
//饿汉式
class Bank{
//1.私有化类的构造器
private Bank(){
}
//2.内部创建类的对象
//4.要求此对象也必须声明为静态的
private static Bank instance = new Bank();
//3.提供公共的静态的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}
package com.wdl.day15;
public class SingletonTest {
public static void main(String[] args) {
Bank bank1 = Bank.instance;
// Bank.instance = null;
Bank bank2 = Bank.instance;
System.out.println(bank1 == bank2);
}
}
class Bank{
private Bank(){
}
public static final Bank instance = new Bank();
}
懒汉式
package com.wdl.day14;
/*
* 单例模式的懒汉式实现
*
*/
public class SingletonTest2 {
public static void main(String[] args) {
Order order1 = Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1 == order2);
}
}
class Order{
//1.私有化类的构造器
private Order(){
}
//2.声明当前类对象,没有初始化
//4.此对象也必须声明为static的
private static Order instance = null;
//3.声明public、static的返回当前类对象的方法
public static Order getInstance(){
if(instance == null){
instance = new Order();
}
return instance;
}
}
解决线程不安全问题
package com.atguigu.java1;
/**
* 使用同步机制将单例模式中的懒汉式改写为线程安全的
*
* @author shkstart
* @create 2019-02-15 下午 2:50
*/
public class BankTest {
}
class Bank{
private Bank(){}
private static Bank instance = null;
public static Bank getInstance(){
//方式一:效率稍差
// synchronized (Bank.class) {
// if(instance == null){
//
// instance = new Bank();
// }
// return instance;
// }
//方式二:效率更高
if(instance == null){
synchronized (Bank.class) {
if(instance == null){
instance = new Bank();
}
}
}
return instance;
}
}
应用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czbCg4m3-1631633254324)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815194141846.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cZVK1wYA-1631633254325)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815195114809.png)]
main()方法
main()方法的使用说明:
- main()方法作为程序的入口
- main()方法也是一个普通的静态方法
- main()方法可以作为我们与控制台交互的方式。(之前:使用Scanner)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFtl1AyR-1631633254326)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815195907304.png)]
代码块
1. 代码块的作用:用来初始化类、对象
2. 代码块如果有修饰的话,只能使用static.
3. 分类:静态代码块 vs 非静态代码块
4. 静态代码块
>内部可以有输出语句
>随着类的加载而执行,而且只执行一次
>作用:初始化类的信息
>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
>静态代码块的执行要优先于非静态代码块的执行
>静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构
5. 非静态代码块
>内部可以有输出语句
>随着对象的创建而执行
>每创建一个对象,就执行一次非静态代码块
>作用:可以在创建对象时,对对象的属性等进行初始化
>如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行
>非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法
package com.wdl.day14;
public class BlockTest {
public static void main(String[] args) {
String desc = Person.desc;
System.out.println(desc);
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.age);
Person.info();
}
}
class Person{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//非static的代码块
{
System.out.println("hello, block - 2");
}
{
System.out.println("hello, block - 1");
//调用非静态结构
age = 1;
eat();
//调用静态结构
desc = "我是一个爱学习的人1";
info();
}
//static的代码块
static{
System.out.println("hello,static block-2");
}
static{
System.out.println("hello,static block-1");
//调用静态结构
desc = "我是一个爱学习的人";
info();
//不可以调用非静态结构
// eat();
// name = "Tom";
}
//方法
public void eat(){
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public static void info(){
System.out.println("我是一个快乐的人!");
}
}
题目一
总结:由父及子,静态先行
package com.atguigu.java3;
//总结:由父及子,静态先行
class Root{
static{
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root(){
super();
System.out.println("Root的无参数的构造器");
}
}
class Mid extends Root{
static{
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid(){
super();
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数构造器,其参数值:"
+ msg);
}
}
class Leaf extends Mid{
static{
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf(){
//通过super调用父类中有一个字符串参数的构造器
super("尚硅谷");
System.out.println("Leaf的构造器");
}
}
public class LeafTest{
public static void main(String[] args){
new Leaf();
System.out.println();
new Leaf();
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yz9UneM7-1631633254328)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210815202131049.png)]
对属性可以赋值的位置
对属性可以赋值的位置:
①默认初始化
②显式初始化/⑤在代码块中赋值
③构造器中初始化
④有了对象以后,可以通过"对象.属性"或"对象.方法"的方式,进行赋值
执行的先后顺序:① - ② / ⑤ - ③ - ④
package com.atguigu.java3;
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
System.out.println(order.orderId);
}
}
class Order{
int orderId = 3;
{
orderId = 4;
}
}
final关键字
- final可以用来修饰的结构:类、方法、变量
- final 用来修饰一个类:此类不能被其他类所继承。
比如:String类、System类、StringBuffer类 - final 用来修饰方法:表明此方法不可以被重写
比如:Object类中getClass(); - final 用来修饰变量:此时的"变量"就称为是一个常量
4.1 final修饰属性:可以考虑赋值的位置有:1.显式初始化、2.代码块中初始化、3.构造器中初始化
4.2 final修饰局部变量:
尤其是使用final修饰形参时,表明此形参是一个常量。当我们调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。
static final 用来修饰属性:全局常量
package com.wdl.day14;
public class FinalTest {
final int WIDTH = 0;
final int LEFT;
final int RIGHT;
// final int DOWN;
{
LEFT = 1;
}
public FinalTest(){
RIGHT = 2;
}
public FinalTest(int n){
RIGHT = n;
}
// public void setDown(int down){
// this.DOWN = down;
// }
public void doWidth(){
// width = 20;
}
public void show(){
final int NUM = 10;//常量
// NUM += 20;
}
public void show(final int num){
// num = 20;//编译不通过
System.out.println(num);
}
public static void main(String[] args) {
int num = 10;
num = num + 5;
FinalTest test = new FinalTest();
// test.setDown(3);
test.show(10);
}
}
final class FinalA{
}
//class B extends FinalA{
//
//}
//class C extends String{
//
//}
class AA{
public final void show(){
}
}
class BB extends AA{
// public void show(){
//
// }
}
题目一
正确
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ETqxt3xf-1631633254329)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816110605097.png)]
abstract关键字
abstract关键字的使用
1.abstract:抽象的
2.abstract可以用来修饰的结构:类、方法
3. abstract修饰类:抽象类
> 此类不能实例化
> 抽象类中一定有构造器,便于子类实例化时调用(涉及:子类对象实例化的全过程)
> 开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作
4. abstract修饰方法:抽象方法
> 抽象方法只有方法的声明,没有方法体
> 包含抽象方法的类,一定是一个抽象类。反之,抽象类中可以没有抽象方法的。
> 若子类重写了父类中的所有的抽象方法后,此子类方可实例化
若子类没有重写父类中的所有的抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
abstract使用上的注意点:
1.abstract不能用来修饰:属性、构造器等结构
2.abstract不能用来修饰私有方法、静态方法、final的方法、final的类
package com.wdl.day15;
public class AbstractTest {
public static void main(String[] args) {
//一旦Person类抽象了,就不可实例化
// Person p1 = new Person();
// p1.eat();
}
}
abstract class Creature{
public abstract void breath();
}
abstract class Person extends Creature{
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
//不是抽象方法:
// public void eat(){
//
// }
//抽象方法
public abstract void eat();
public void walk(){
System.out.println("人走路");
}
}
class Student extends Person{
public Student(String name,int age){
super(name,age);
}
public Student(){
}
public void eat(){
System.out.println("学生多吃有营养的食物");
}
@Override
public void breath() {
System.out.println("学生应该呼吸新鲜的没有雾霾的空气");
}
}
抽象类的匿名子类
package com.wdl.day15;
/*
* 抽象类的匿名子类
*
*/
public class PersonTest {
public static void main(String[] args) {
method(new Student());//匿名对象
Worker worker = new Worker();
method1(worker);//非匿名的类非匿名的对象
method1(new Worker());//非匿名的类匿名的对象
System.out.println("********************");
//创建了一匿名子类的对象:p
Person p = new Person(){
@Override
public void eat() {
System.out.println("吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸");
}
};
method1(p);
System.out.println("********************");
//创建匿名子类的匿名对象
method1(new Person(){
@Override
public void eat() {
System.out.println("吃好吃东西");
}
@Override
public void breath() {
System.out.println("好好呼吸新鲜空气");
}
});
}
public static void method1(Person p){
p.eat();
p.breath();
}
public static void method(Student s){
}
}
class Worker extends Person{
@Override
public void eat() {
}
@Override
public void breath() {
}
}
模板方法设计模式(TemplateMethod)
抽象类体现的就是一种模板模式的设计,抽象类作为多个子类的通用模
板,子类在抽象类的基础上进行扩展、改造,但子类总体上会保留抽象
类的行为方式。
解决的问题:
当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vBVDXmS2-1631633254330)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816150210963.png)]
interface关键字
接口的使用
1.接口使用interface来定义
2.Java中,接口和类是并列的两个结构
3.如何定义接口:定义接口中的成员
3.1 JDK7及以前:只能定义全局常量和抽象方法
>全局常量:public static final的.但是书写时,可以省略不写
>抽象方法:public abstract的
3.2 JDK8:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法(略)
4. 接口中不能定义构造器的!意味着接口不可以实例化
5. Java开发中,接口通过让类去实现(implements)的方式来使用.
如果实现类覆盖了接口中的所有抽象方法,则此实现类就可以实例化
如果实现类没有覆盖接口中所有的抽象方法,则此实现类仍为一个抽象类
6. Java类可以实现多个接口 --->弥补了Java单继承性的局限性
格式:class AA extends BB implements CC,DD,EE
7. 接口与接口之间可以继承,而且可以多继承
*******************************
8. 接口的具体使用,体现多态性
9. 接口,实际上可以看做是一种规范
package com.wdl.day15;
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.MIN_SPEED);
// Flyable.MIN_SPEED = 2;
Plane plane = new Plane();
plane.fly();
}
}
interface Flyable{
//全局常量
public static final int MAX_SPEED = 7900;//第一宇宙速度
int MIN_SPEED = 1;//省略了public static final
//抽象方法
public abstract void fly();
//省略了public abstract
void stop();
//Interfaces cannot have constructors
// public Flyable(){
//
// }
}
interface Attackable{
void attack();
}
class Plane implements Flyable{
@Override
public void fly() {
System.out.println("通过引擎起飞");
}
@Override
public void stop() {
System.out.println("驾驶员减速停止");
}
}
abstract class Kite implements Flyable{
@Override
public void fly() {
}
}
class Bullet extends Object implements Flyable,Attackable,CC{
@Override
public void attack() {
// TODO Auto-generated method stub
}
@Override
public void fly() {
// TODO Auto-generated method stub
}
@Override
public void stop() {
// TODO Auto-generated method stub
}
@Override
public void method1() {
// TODO Auto-generated method stub
}
@Override
public void method2() {
// TODO Auto-generated method stub
}
}
//************************************
interface AA{
void method1();
}
interface BB{
void method2();
}
interface CC extends AA,BB{
}
题目一
面试题:抽象类与接口有哪些异同?
相同点:不能实例化,都可以被继承+
不同点:抽象类:有构造器。接口:不能声明构造器。
多继承vs单继承
题目二
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j1ECKbay-1631633254332)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816173040793.png)]
题目三
public static final
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gazuzrdb-1631633254333)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816173332436.png)]
代理模式(Proxy)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HAaPjTcN-1631633254334)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816165746590.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3RAKxfyT-1631633254336)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816170203481.png)]
package com.wdl.day15;
/*
* 接口的应用:代理模式
*
*/
public class NetWorkTest {
public static void main(String[] args) {
Server server = new Server();
// server.browse();
ProxyServer proxyServer = new ProxyServer(server);
proxyServer.browse();
}
}
interface NetWork{
public void browse();
}
//被代理类
class Server implements NetWork{
@Override
public void browse() {
System.out.println("真实的服务器访问网络");
}
}
//代理类
class ProxyServer implements NetWork{
private NetWork work;
public ProxyServer(NetWork work){
this.work = work;
}
public void check(){
System.out.println("联网之前的检查工作");
}
@Override
public void browse() {
check();
work.browse();
}
}
工厂模式
工厂模式:实现了创建者与调用者的分离,即将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的。其实设计模式和面向对象设计原则都是为了使得开发项目更加容易扩展和维护,解决方式就是一个“分工”。
无工厂模式
package com.atguigu.pattern.factory.nofactory;
interface Car{
void run();
}
class Audi implements Car{
public void run() {
System.out.println("奥迪在跑");
} }
class BYD implements Car{
public void run() {
System.out.println("比亚迪在跑");
} }
public class Client01 {
public static void main(String[] args) {
Car a = new Audi();
Car b = new BYD();
a.run();
b.run();
} }
简单工厂模式
用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码)
缺点:对于增加新产品,不修改代码的话,是无法扩展的。违反了开闭原则(对扩展开放;对修改封闭)。
package com.atguigu.pattern.factory.simple;
interface Car {
void run();
}
class Audi implements Car {
public void run() {
System.out.println("奥迪在跑");
} }
class BYD implements Car {
public void run() {
System.out.println("比亚迪在跑");
} }
//工厂类
class CarFactory {
//方式一
public static Car getCar(String type) {
if ("奥迪".equals(type)) {
return new Audi();
} else if ("比亚迪".equals(type)) {
return new BYD();
} else {
return null; } }
//方式二
// public static Car getAudi() {
// return new Audi();
// }
//
// public static Car getByd() {
// return new BYD();
// } }
public class Client02 {
public static void main(String[] args) {
Car a = CarFactory.getCar("奥迪");
a.run();
Car b = CarFactory.getCar("比亚迪");
b.run();
} }
工厂方法模式
用来生产同一等级结构中的固定产品。
package com.atguigu.pattern.factory.method;
interface Car{
void run();
}
//两个实现类
class Audi implements Car{
public void run() {
System.out.println("奥迪在跑");
} }
class BYD implements Car{
public void run() {
System.out.println("比亚迪在跑");
} }
//工厂接口
interface Factory{
Car getCar();
}
//两个工厂类
class AudiFactory implements Factory{
public Audi getCar(){
return new Audi();
} }
class BydFactory implements Factory{
public BYD getCar(){
return new BYD();
} }
public class Client {
public static void main(String[] args) {
Car a = new AudiFactory().getCar();
Car b = new BydFactory().getCar();
a.run();
b.run();
} }
抽象工厂模式
用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)
比较对象大小
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AAy0onm4-1631633254337)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210816184326113.png)]
Java8中接口的新特性
知识点1:
接口中定义的静态方法,只能通过接口来调用。 CompareA.method1();
知识点2:
通过实现类的对象,可以调用接口中的默认方法。如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法 s.method2();
知识点3:
如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。–>类优先原则
知识点4:
如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,那么在实现类没有重写此方法的情况下,报错。–>接口冲突。
这就需要我们必须在实现类中重写此方法 s.method3();
知识点5:
如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用 的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
package com.wdl.day15;
public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
// SubClass.method1();
//知识点1:接口中定义的静态方法,只能通过接口来调用。
CompareA.method1();
//知识点2:通过实现类的对象,可以调用接口中的默认方法。
//如果实现类重写了接口中的默认方法,调用时,仍然调用的是重写以后的方法
s.method2();
//知识点3:如果子类(或实现类)继承的父类和实现的接口中声明了同名同参数的默认方法,
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法。-->类优先原则
//知识点4:如果实现类实现了多个接口,而这多个接口中定义了同名同参数的默认方法,
//那么在实现类没有重写此方法的情况下,报错。-->接口冲突。
//这就需要我们必须在实现类中重写此方法
s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("SubClass:上海");
}
public void method3(){
System.out.println("SubClass:深圳");
}
//知识点5:如何在子类(或实现类)的方法中调用父类、接口中被重写的方法
public void myMethod(){
method3();//调用自己定义的重写的方法
super.method3();//调用的是父类中声明的
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}
内部类
类的内部成员之五:内部类
1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类
2.内部类的分类:成员内部类(静态、非静态) vs 局部内部类(方法内、代码块内、构造器内)
3.成员内部类:
一方面,作为外部类的成员:
>调用外部类的结构
>可以被static修饰
>可以被4种不同的权限修饰
另一方面,作为一个类:
> 类内可以定义属性、方法、构造器等
> 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
> 可以被abstract修饰
4.关注如下的3个问题
4.1 如何实例化成员内部类的对象
4.2 如何在成员内部类中区分调用外部类的结构
4.3 开发中局部内部类的使用 见《InnerClassTest1.java》
package com.wdl.day15;
public class InnerClassTest {
public static void main(String[] args) {
//创建Dog实例(静态的成员内部类):
Person.Dog dog = new Person.Dog();
dog.show();
//创建Bird实例(非静态的成员内部类):
// Person.Bird bird = new Person.Bird();//错误的
Person p = new Person();
Person.Bird bird = p.new Bird();
bird.sing();
System.out.println();
bird.display("黄鹂");
}
}
class Person{
String name = "小明";
int age;
public void eat(){
System.out.println("人:吃饭");
}
//静态成员内部类
static class Dog{
String name;
int age;
public void show(){
System.out.println("卡拉是条狗");
// eat();
}
}
//非静态成员内部类
class Bird{
String name = "杜鹃";
public Bird(){
}
public void sing(){
System.out.println("我是一只小小鸟");
Person.this.eat();//调用外部类的非静态属性
eat();
System.out.println(age);
}
public void display(String name){
System.out.println(name);//方法的形参
System.out.println(this.name);//内部类的属性
System.out.println(Person.this.name);//外部类的属性
}
}
public void method(){
//局部内部类
class AA{
}
}
{
//局部内部类
class BB{
}
}
public Person(){
//局部内部类
class CC{
}
}
}
使用
package com.wdl.day15;
public class InnerClassTest1 {
//开发中很少见
public void method(){
//局部内部类
class AA{
}
}
//返回一个实现了Comparable接口的类的对象
public Comparable getComparable(){
//创建一个实现了Comparable接口的类:局部内部类
//方式一:
// class MyComparable implements Comparable{
//
// @Override
// public int compareTo(Object o) {
// return 0;
// }
//
// }
//
// return new MyComparable();
//方式二:
return new Comparable(){
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
注意点
在局部内部类的方法中(比如:show)如果调用局部内部类所声明的方法(比如:method)中的局部变量(比如:num)的话,要求此局部变量声明为final的。
jdk 7及之前版本:要求此局部变量显式的声明为final的
jdk 8及之后的版本:可以省略final的声明
package com.atguigu.java;
public class InnerClassTest {
// public void onCreate(){
//
// int number = 10;
//
// View.OnClickListern listener = new View.OnClickListener(){
//
// public void onClick(){
// System.out.println("hello!");
// System.out.println(number);
// }
//
// }
//
// button.setOnClickListener(listener);
//
// }
public void method(){
//局部变量
int num = 10;
class AA{
public void show(){
// num = 20;
System.out.println(num);
}
}
}
}
总结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MET1wtkn-1631633254338)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210817094307361.png)]
异常
异常分类
Error:
Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。
Exception:
其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如:
空指针访问
试图读取不存在的文件
网络连接中断
数组角标越界
体系结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-c1kGzhgu-1631633254339)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210817102901922.png)]
常见异常
异常体系结构
java.lang.Throwable
|-----java.lang.Error:一般不编写针对性的代码进行处理
|-----java.lang.Exception:可以进行异常的处理
|------编译时异常(checked)
|-----IOException
|-----FileNotFoundException
|-----ClassNotFoundException
|------运行时异常(unchecked,RuntimeException)
|-----NullPointerException
|-----ArrayIndexOutOfBoundsException
|-----ClassCastException
|-----NumberFormatException
|-----InputMismatchException
|-----ArithmeticException
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.util.Date;
import java.util.Scanner;
import org.junit.Test;
public class ExceptionTest {
//******************以下是编译时异常***************************
@Test
public void test7(){
// File file = new File("hello.txt");
// FileInputStream fis = new FileInputStream(file);
//
// int data = fis.read();
// while(data != -1){
// System.out.print((char)data);
// data = fis.read();
// }
//
// fis.close();
}
//******************以下是运行时异常***************************
//ArithmeticException
@Test
public void test6(){
int a = 10;
int b = 0;
System.out.println(a / b);
}
//InputMismatchException
@Test
public void test5(){
Scanner scanner = new Scanner(System.in);
int score = scanner.nextInt();
System.out.println(score);
scanner.close();
}
//NumberFormatException
@Test
public void test4(){
String str = "123";
str = "abc";
int num = Integer.parseInt(str);
}
//ClassCastException
@Test
public void test3(){
Object obj = new Date();
String str = (String)obj;
}
//IndexOutOfBoundsException
@Test
public void test2(){
//ArrayIndexOutOfBoundsException
// int[] arr = new int[10];
// System.out.println(arr[10]);
//StringIndexOutOfBoundsException
String str = "abc";
System.out.println(str.charAt(3));
}
//NullPointerException
@Test
public void test1(){
// int[] arr = null;
// System.out.println(arr[3]);
String str = "abc";
str = null;
System.out.println(str.charAt(0));
}
}
异常处理机制
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TdbyUxeH-1631633254340)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210817150509404.png)]
抓抛模型
过程一:"抛":程序在正常执行的过程中,一旦出现异常,就会在异常代码处生成一个对应异常类的对象。
并将此对象抛出。
一旦抛出对象以后,其后的代码就不再执行。
关于异常对象的产生:① 系统自动生成的异常对象
② 手动的生成一个异常对象,并抛出(throw)
过程二:"抓":可以理解为异常的处理方式:① try-catch-finally ② throws
方式一(try-catch-finally)
try-catch-finally的使用
try{
//可能出现异常的代码
}catch(异常类型1 变量名1){
//处理异常的方式1
}catch(异常类型2 变量名2){
//处理异常的方式2
}catch(异常类型3 变量名3){
//处理异常的方式3
}
....
finally{
//一定会执行的代码
}
说明:
1. finally是可选的。
2. 使用try将可能出现异常代码包装起来,在执行过程中,一旦出现异常,就会生成一个对应异常类的对象
的类型,去catch中进行匹配
3. 一旦try中的异常对象匹配到某一个catch时,就进入catch中进行异常的处理。一旦处理完成,就跳出当
try-catch结构(在没有写finally的情况)。继续执行其后的代码
4. catch中的异常类型如果没有子父类关系,则谁声明在上,谁声明在下无所谓。
catch中的异常类型如果满足子父类关系,则要求子类一定声明在父类的上面。否则,报错
5. 常用的异常对象处理的方式: ① String getMessage() ② printStackTrace()
6. 在try结构中声明的变量,再出了try结构以后,就不能再被调用
7. try-catch-finally结构可以嵌套
体会1:使用try-catch-finally处理编译时异常,是得程序在编译时就不再报错,但是运行时仍可能报错。
相当于我们使用try-catch-finally将一个编译时可能出现的异常,延迟到运行时出现。
体会2:开发中,由于运行时异常比较常见,所以我们通常就不针对运行时异常编写try-catch-finally了。
针对于编译时异常,我们说一定要考虑异常的处理。
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
public class ExceptionTest1 {
@Test
public void test2(){
try{
File file = new File("hello.txt");
FileInputStream fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
fis.close();
}catch(FileNotFoundException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
@Test
public void test1(){
String str = "123";
str = "abc";
int num = 0;
try{
num = Integer.parseInt(str);
System.out.println("hello-----1");
}catch(NumberFormatException e){
// System.out.println("出现数值转换异常了,不要着急....");
//String getMessage():
// System.out.println(e.getMessage());
//printStackTrace():
e.printStackTrace();
}catch(NullPointerException e){
System.out.println("出现空指针异常了,不要着急....");
}catch(Exception e){
System.out.println("出现异常了,不要着急....");
}
System.out.println(num);
System.out.println("hello-----2");
}
}
finally
1.finally是可选的
2.finally中声明的是一定会被执行的代码。即使catch中又出现异常了,try中有return语句,catch中有return语句等情况。
3.像数据库连接、输入输出流、网络编程Socket等资源,JVM是不能自动的回收的,我们需要自己手动的进行资源的 释放。此时的资源释放,就需要声明在finally中。
package com.atguigu.java1;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.Test;
public class FinallyTest {
@Test
public void test2(){
FileInputStream fis = null;
try {
File file = new File("hello1.txt");
fis = new FileInputStream(file);
int data = fis.read();
while(data != -1){
System.out.print((char)data);
data = fis.read();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(fis != null)
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Test
public void testMethod(){
int num = method();
System.out.println(num);
}
public int method(){
try{
int[] arr = new int[10];
System.out.println(arr[10]);
return 1;
}catch(ArrayIndexOutOfBoundsException e){
e.printStackTrace();
return 2;
}finally{
System.out.println("我一定会被执行");
return 3;
}
}
@Test
public void test1(){
try{
int a = 10;
int b = 0;
System.out.println(a / b);
}catch(ArithmeticException e){
e.printStackTrace();
// int[] arr = new int[10];
// System.out.println(arr[10]);
}catch(Exception e){
e.printStackTrace();
}
// System.out.println("我好帅啊!!!~~");
finally{
System.out.println("我好帅啊~~");
}
}
}
方式二(throws + 异常类型)
- "throws + 异常类型"写在方法的声明处。指明此方法执行时,可能会抛出的异常类型。
一旦当方法体执行时,出现异常,仍会在异常代码处生成一个异常类的对象,此对象满足throws后异常
类型时,就会被抛出。异常代码后续的代码,就不再执行!
体会
try-catch-finally:真正的将异常给处理掉了。
throws的方式只是将异常抛给了方法的调用者。 并没有真正将异常处理掉。
开发中如何选择使用try-catch-finally 还是使用throws
1 如果父类中被重写的方法没有throws方式处理异常,则子类重写的方法也不能使用throws,意味着如果
子类重写的方法中有异常,必须使用try-catch-finally方式处理。
2 执行的方法a中,先后又调用了另外的几个方法,这几个方法是递进关系执行的。我们建议这几个方法使用throws 的方式进行处理。而执行的方法a可以考虑使用try-catch-finally方式进行处理。
用户自定义异常类
如何自定义异常类?
- 继承于现有的异常结构:RuntimeException 、Exception
- 提供全局常量:serialVersionUID
- 提供重载的构造器
package com.atguigu.java2;
/*
* 如何自定义异常类?
* 1. 继承于现有的异常结构:RuntimeException 、Exception
* 2. 提供全局常量:serialVersionUID
* 3. 提供重载的构造器
*
*/
public class MyException extends Exception{
static final long serialVersionUID = -7034897193246939L;
public MyException(){
}
public MyException(String msg){
super(msg);
}
}
package com.atguigu.java2;
public class StudentTest {
public static void main(String[] args) {
try {
Student s = new Student();
s.regist(-1001);
System.out.println(s);
} catch (Exception e) {
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class Student{
private int id;
public void regist(int id) throws Exception {
if(id > 0){
this.id = id;
}else{
// System.out.println("您输入的数据非法!");
//手动抛出异常对象
// throw new RuntimeException("您输入的数据非法!");
// throw new Exception("您输入的数据非法!");
throw new MyException("不能输入负数");
//错误的
// throw new String("不能输入负数");
}
}
@Override
public String toString() {
return "Student [id=" + id + "]";
}
}
题目一
package com.atguigu.java2;
public class ReturnExceptionDemo {
static void methodA() {
try {
System.out.println("进入方法A");
throw new RuntimeException("制造异常");
} finally {
System.out.println("用A方法的finally");
}
}
static void methodB() {
try {
System.out.println("进入方法B");
return;
} finally {
System.out.println("调用B方法的finally");
}
}
public static void main(String[] args) {
try {
methodA();
} catch (Exception e) {
System.out.println(e.getMessage());
}
methodB();
}
}
题目二
throw和throws 区别:
throw表示抛出一一个异常类的对象,生成异常对象的过程。声明在方法体内。
throws属于异常处理的一种方式,声明在方法的声明处。