admin管理员组文章数量:1565292
MarkDown学习
标题
三级标题
四级标题
字体
hello,word!
hello,word!
hello,word!
hello,word!
引用
选择狂神说Java,走向人生巅峰
分割线
图片
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LflUxTP0-1600842737053)(C:\Users\wjq913\Desktop\阿里园区数据大屏.png)]
超链接
点击跳转到狂神说博客
列表
- A
- B
- C
- A
- B
- C
表格
名字 | 性别 | 生日 | |
---|---|---|---|
张三 | 男 | 1997.1.1 |
代码
public
CMD基础学习
打开CMD的方式
1.开始+系统+命令提示符
2.Win键+R 输入CMD打开控制台(推荐使用)
3.在任意文件夹下面,按住shift键+鼠标右击,在此处打开命令窗口
4.资源管理器的地址栏前面加上CMD路径
管理员方式运行:选择以管理员方式运行
常用的DOS命令
#盘符切换 D:
#查看当前目录下的所有文件 dir
#切换目录 cd(change directory)
#切换到f盘 cd /d f:
#切换到E盘下的IDE文件夹 cd /d E:\IDE
#返回上一级 cd ..
#清理屏幕 cls (clear screen)
#退出终端 exit
#查看电脑的IP ipconfing
#打开应用
计算器calc
画图mspaint
记事本notepad
#ping命令
ping www.baidu
#文件操作
创建文件夹md
移除文件夹rd
创建文件 cd>a.txt
删除文件 del a.txt
卸载JDK
1.删除Java的安装目录
2.删除JAVA_HOME
3.删除path下关于Java的目录
4.java -version
安装JDK
1.百度搜索JDK8,找到下载地址
2.同意协议
3.下载电脑对应版本
4.双击安装JDK
5.记住安装的路径
6.配置环境变量
1.我的电脑–>右键–>属性
2.环境变量–>JAVA_HOME
3.配置path变量
7.测试JDK是否安装成功
1.打开cmd
2.java -version
NotePad++
Java学习流程及注意点
-
1.Java开发流程?
- JavaSE
- 数据库
- 前端
- Javaweb
- SSM框架
- Linux
- springboot
- springcloud
- hadoop
-
2.如何更好更高效的学习Java?
- 多写代码、多写笔记、多写文章
- 多练交流、多练思维、多练技能
- 多分享知识、多提问怎么了、多思考为什么
- 最重要坚持
-
3.学习准备:
- 博客Blog:
- 需要总结和思考。
- 提升文笔组织能力
- 提升学习和总结能力
- 提升逻辑思维能力
- 帮助他人,结交朋友
Hello World
1.随便新建一个文件夹,存放代码
2.新建一个java文件
- 文件后缀名为.java
- Hello.java
- 【注意点】系统可能没有显示文件后缀名,需要手动打开
3.编写代码
public class Hello{
public static void main(String[] args){
System.out.print("hello,world!");
}
}
4.编译javac java文件,会生成一个class文件
5.运行class文件,java class文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qdGC8xgW-1600842737060)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200604212102468.png)]
可能会遇到的情况
1.每个单词的大小写不能出现问题,java是大小写敏感的
2.尽量使用英文
3.文件名和类名必须保持一致,并且首字母大写
4.符号使用了中文
java程序运行机制
编译型:一本书直接翻译好,高效快捷,但后续有更改要重新花费成本再次翻译
解释型:身边有个翻译官,看一句翻译一句,实时翻译
程序运行机制:源程序*.java文件–>java编译器–>字节码^.class文件–>类装载器–>字节码校验器–>解释器–>操作系统平台
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tOZtCSFA-1600842737065)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200721115142462.png)]
IDEA
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务套。所有具备这一特性的软件或者软件套(组)都可以叫集成开发环境。如微软的Visual Studio系列,Borland的[C++ Builder](https://baike.baidu/item/C%2B%2B Builder)、Delphi系列等。该程序可以独立运行,也可以和其它程序并用。IDE多被用于开发HTML应用软件。例如,许多人在设计网站时使用IDE(如HomeSite、DreamWeaver等),因为很多项任务会自动生成。
IDEA:https://www.jetbrains/
JAVASE基础
标识符
所有标识符都应该以字母(A-Z或者a-z)、美元符($)、或者下划线(_)开始
首字母之后可以是字母(A-Z或者a-z)、美元符($)、下划线(_)或数字的任意字符组合
不能使用关键字作为变量名或方法名
标识符是大小写敏感的
可以使用中文命名,但一般不建议这样去使用,也不及建议使用拼音,很low
数据类型
强类型语言
要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用
弱类型语言
java的数据类型分为两大类:
基本类型(primitive type)
引用类型(reference type)
什么是字节?
位(bit):是计算机内部数据存储的最小单位,11001100是一个八位二进制数
字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示
1B(byte,字节)= 8bit(位)
字符:是指计算机中使用的字母、数字、字和符号
1bit表示1位
1Byte表示一个字节 1B=8b
1024B =1KB
1024KB=1M
1024M =1G
基本数据类型
数值类型
整数类型:byte 占1个字节范围:-128~127
short 占2个字节范围:-32768~32767
int 占4个字节范围:-2147483648~2147483647
long 占8个字节范围:-923372036854775808~923372036854775807
浮点类型(小数): float 占4个字节
double 占8个字节
字符类型: char 占2个字节
boolean类型
占1位 其值只有true和false两个
引用数据类型
类:字符串String
接口
数组
类型拓展
public class Demo03 {
public static void main(String[] args){
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i = 10;
int i2 = 010; //八进制0
int i3 = 0x10; //十六进制0x 0~9 A~F
System.out.println(i);
System.out.println(i2);
System.out.println(i3);
System.out.println("==========================================================");
//==================================================================
//浮点数拓展? 银行业务怎么表示?钱 --> BigDecimal 数学工具类
//float 有限的 离散的 舍入误差 舍入误差 大约 接近但不等于
//double
//最好完全避免使用浮点数进行比较
//最好完全避免使用浮点数进行比较
//最好完全避免使用浮点数进行比较
float f = 0.1f; //0.1
double d = 1.0/10; //0.1
System.out.println(f==d); //false
System.out.println(f);
System.out.println(d);
float d1 = 231313123123123f;
float d2 = d1+1;
System.out.println(d1==d2); //true
System.out.println("==================================================================");
//==================================================================
//字符拓展?
char c1 = 'A';
char c2 = '中';
System.out.println(c1);
System.out.println((int)c1); //强制转换
System.out.println(c2);
System.out.println((int)c2); //强制转换
//所有的字符本质还是数字
//编码问题 --> Unicode表:97=a 65=A 占2字节 65536个字符 excel表格2的16次方=65536个长度
// U0000~UFFFF
char c3 = '\u0061';
System.out.println(c3);
System.out.println("==================================================================");
//==================================================================
//转义字符
// \t 制表符tab
// \n 换行
System.out.println("hello\tworld");
System.out.println("hello\nworld");
System.out.println("==================================================================");
//==================================================================
String sa = new String("hello world");
String sb = new String("hello world");
System.out.println(sa == sb); //false
String sc = "hello world";
String sd = "hello world";
System.out.println(sc == sd); //true
//对象 从内存分析
System.out.println("==================================================================");
//==================================================================
//布尔值拓展
boolean flag = true;
//if (flag==true){} Less is More!
if (flag) {
System.out.println("这个东西是真的");
}
}
}
类型转换
由于Java是强类型语言,所以要进行有限运算的时候的,需要用到类型转换。
低--------------------------------------------------------------------------->高
byte,short,char --> int --> long --> float --> double (小数的优先级大于整数)
运算中,不同类型的数据先转化为同一类型,然后进行运算
强制转换 (类型)变量名 高–>低
自动转换 低–>高
public class Demo05 {
public static void main(String[] args){
int i = 128;
byte b = (byte)i; //byte最大值127,内存溢出
double d = i;
//强制转换 (类型)变量名 高-->低
//自动转换 低-->高
System.out.println(i);
System.out.println(b);
System.out.println(d);
System.out.println("==================================================");
//==================================================================
/*
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把大容量转换为低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题
*/
System.out.println((int)23.7);
System.out.println((int)-45.89f);
System.out.println("==================================================");
//==================================================================
char c = 'a';
int t = c+1;
System.out.println(t);
System.out.println((char) t);
}
}
操作时应注意数据溢出的问题:
public class Demo06 {
public static void main(String[] args) {
//操作比较大的数的时候,注意溢出问题
//JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money*years; //结果为-1474836480,计算时数据溢出了
System.out.println(total);
long total2 = money*years; //结果仍为-1474836480,默认是int,转换之前已经存在问题了
System.out.println(total2);
long total3 = money*((long)years); //先把一个数转换为Long
System.out.println(total3);
//L l
}
}
变量
变量是什么?:就是可以变化的量(一块内存空间是确定的,但这块空间存什么东西是不确定的)
java是一种强类型语言,每个变量都必须声明其类型
java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
注意事项:
每个变量都有类型,类型可以是基本类型,也可以是引用类型(String字符串就是一种类)
变量名必须是合法的标识符
变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
变量作用域
public class Demo08 {
//属性:变量
//类变量 static 是从属于类Demo08的
static double salary = 2500;
//===================================================================================
//实例变量:从属于对象(从属于这个类Demo08);如果不自行初始化,这个类型的默认值 0 0.0 u0000
//布尔值:默认是false
//除了基本类型,其余的默认值都是null
int age;
String name;
//===================================================================================
//main方法
public static void main(String[] args) {
//局部变量:(从属于这个方法)必须声明和初始化值
int i = 10;
System.out.println(i);
System.out.println("================================================");
//===================================================================================
//实例变量:
//变量类型 变量名字 = new Demo08();
Demo08 demo08 = new Demo08();
System.out.println(demo08.age); //0
System.out.println(demo08.name); //null
System.out.println("================================================");
//===================================================================================
//类变量 static
System.out.println(salary);
}
//其他方法
public void add(){}
}
常量
常量(Constant):初始化(initialize)后不能再改变值! 不会变动的值。
所谓常量可以理解为一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变
final 常量名 = 值;
final double PI =3.14;
变量的命名规范
所有变量、方法、类名:见名知意
类成员变量:首字母小写和驼峰原则:monthSalary 除了第一个单词以外,后面的单词首字母大写 lastName
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线:MAX_VALUE
类名:首字母大写和驼峰原则:Man,GoodMan
方法名:首字母小写和驼峰原则:run(),runRun()
运算符
**java语言支持如下运算符:**优先级,用()提升优先级
- 算数运算符:+、-、*、/、%模、++、–
- 赋值运算符:=
- 关系运算符:>、<、>=、<=、==、!=instanceof
- 逻辑运算符:&&与、||或、!非
- 位运算符:&、|、^、~、>>(算数右移)、<<、>>>(逻辑右移)
- 条件运算符: ?:
- 扩展运算符:+=、-=、*=、/=
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yLhxflmn-1600842737067)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200717191052265.png)]
算数运算符
package operator;
public class Demo01 {
public static void main(String[] args) {
//二元运算符
//Ctrl+D:复制当前行到下一行
int a = 10;
int b = 20;
int c = 25;
int d = 25;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/(double)b);
System.out.println(a%b);
}
}
package operator;
public class Demo02 {
public static void main(String[] args) {
long a =123123123123123L;
int b = 123;
short c = 10;
byte d = 8;
System.out.println(a+b+c+d); //Long
System.out.println(b+c+d); //int
System.out.println(c+d); //int
System.out.println((double)c+d);
}
}
关系运算符
package operator;
public class Demo03 {
public static void main(String[] args) {
//关系运算符返回的结果: 正确,错误-->布尔值
//if
int a = 10;
int b = 20;
int c = 21;
//取余,模运算
System.out.println(c%a); // c/a 21/10=2...1
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
System.out.println(a!=b);
System.out.println(a=b);
}
}
自增自减运算
package operator;
public class Demo04 {
public static void main(String[] args) {
//++自增 ,--自减 一元运算符
int a = 3;
int b = a++; //执行完这行代码后,先给b赋值,再自增
//a=a+1
System.out.println(a);
//a=a+1
int c = ++a; //执行完这行代码前,先自增,再给c赋值
System.out.println(a);
System.out.println(b);
System.out.println(c);
//幂运算 2^3-->2*2*2=8 很多运算,我们会使用一些工具类来操作!
double pow = Math.pow(2, 3);
System.out.println(pow);
}
}
逻辑运算符
package operator;
//逻辑运算符
public class Demo05 {
public static void main(String[] args) {
//与(and) 或(or) 非(取反)
boolean a = true;
boolean b = false;
System.out.println("a && b:"+(a&&b)); //逻辑与运算:两个变量都为真,结果才为true
System.out.println("a || b:"+(a||b)); //逻辑或运算:两个变量有一个为真,结果才为true
System.out.println("! (a && b):"+! (a && b)); //如果是真,则变为假,如果是假则变为真
//短路运算:
int c = 5;
boolean d = (c<4)&&(c++<4); //发生短路,c++没有执行,结果还是5
System.out.println(d);
System.out.println(c);
}
}
位运算符
package operator;
public class Demo06 {
public static void main(String[] args) {
/*
A = 0011 1100
B = 0000 1101
A&B = 0000 1100 与:上下两位都为1,结果才为1,否则为0
A|B = 0011 1101 或:上下两位都为0,结果才为0,否则为1
A^B = 0011 0001 亦或:上下两位相同则为0,否则为1
~B = 1111 0010 取反:颠倒就行
2*8 = 16怎么运算最快 -->2*2*2*2 转换为位运算,效率极高!
<<左移 *2
>>右移 /2
0000 0000-->0
0000 0001-->1
0000 0010-->2
0000 0011-->3
0000 0100-->4
0000 1000-->8
0001 0000-->16
*/
System.out.println(2<<3); //结果为16-->2*(2^3)
}
}
包机制
为了更好地组织类,java提供了包机制,用于区别类名的命名空间。包的本质就是文件夹。
包语句的语法格式为:
package pkg1[.pkg2[].pkg3...];
**一般利用公司域名倒置作为包 名;**www.baidu --> com.baidu.www
为了能够使用某一个包的成员,我们需要java程序中明确导入该包。使用“import”语句可以完成此功能
import package1[.package2...].(classname|*);
一次性导入这个包下所有类:
import com.wjq.base.*;
JavaDoc
Javadoc命令是用来生成自己API文档的
参数信息
- @author 作者名
- @version 版本号
- @since 指明需要最早使用的JDK版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
package com.wjq.base;
/**
* @author Weijiaqi
* @version 1.0
* @since 1.8
*
*/
public class Doc {
String name;
/**
*
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception{
return name;
//用命令生成查找文档:javadoc 参数 java文件
//作业:学会查找使用IDEA生成javadoc文档! 面向百度编程
}
}
用IDEA自动生成JavaDoc文档
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fT3pqDqK-1600842737068)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200621095709136.png)]
基础部分的一切知识,后面几乎都会用到
Java流程控制
scanner对象
之前的基础语法中并没有实现程序和人的交互,但Java提供了这样一个工具类,我们可以获取用户的输入。
java.util.Scanner是Java5的新特性,我们可以通过Scanner类来获取用户的输入。
基本语法
Scanner s = new Scanner(System.in);
通过Scanner类的**next()与nextLine()方法获取输入的字符串,在读取前我们一般要使用hasNext()与hasNextLine()**判断是否有输入的数据。
next():
package com.wjq.scanner;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if (scanner.hasNext()){
//使用next方式接收
String str = scanner.next(); //程序会等待用户输入完毕
System.out.println("输入的内容为:"+str);
}
//凡是属于I/O流的类,如果不关闭会一直占用资源,要养成良好的使用习惯,用完就关掉。
scanner.close();
}
}
nextLine():
package com.wjq.scanner;
import java.util.Scanner;
public class Demo02 {
public static void main(String[] args) {
// 从键盘接收数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方式接收:");
// 判断是否还有输入
if (scanner.hasNextLine()){
String str = scanner.nextLine();
System.out.println("输出的内容为:"+str);
}
scanner.close();
}
}
next()与nextLine()区别:
*next():
- 一定要读取到有效字符后才可以结束输入。
- 对输入有效字符之前遇到的空白。next()方法会自动将其去掉
- 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
- next()不得能到带有空格的字符串
*nextLine():
- 以Enter键作为结束符,也就是说nextLine()方法返回值是输入回车之前的所有字符
- nextLine()可以获得空白
next()与nextLine()对小数和整数等数据的支持:
package com.wjq.scanner;
import java.util.Scanner;
public class DEmo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//从键盘接收数据
int i = 0;
float f = 0.0f;
System.out.println("请输入整数:");
if (scanner.hasNextInt()){
i = scanner.nextInt();
System.out.println("整数数据:"+i);
}else{
System.out.println("对不起,输入的不是整数数据");
}
System.out.println("请输入小数:");
if (scanner.hasNextFloat()){
f = scanner.nextFloat();
System.out.println("小数数据:"+f);
}else{
System.out.println("对不起,输入的不是小数数据");
}
scanner.close();
}
}
拓展练习://输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果;
package com.wjq.scanner;
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
//输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果;
Scanner scanner = new Scanner(System.in);
//定义和
double sum = 0;
//计算输入了多少个数字
int m = 0;
System.out.println("请输入数据:");
//通过循环判断是否还有输入,并在里面对每一次进行求和统计
while(scanner.hasNextDouble()){
double x = scanner.nextDouble();
m = m + 1; //m++;
sum = sum + x;
System.out.println("你输入了第"+m+"个数据,当前结果sum="+sum);
}
System.out.println(m + "个数的和为:" + sum);
System.out.println(m + "个数的平均值是" + (sum / m));
scanner.close();
}
}
顺序结构
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
顺序结构是最简单的算法结构。
语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组形成的,它是任何一个算法都离不开的一种基本算法结构。
package com.wjq.struct;
public class ShunXuDemo {
public static void main(String[] args) {
System.out.println("hello1");
System.out.println("hello2");
System.out.println("hello3");
System.out.println("hello4");
System.out.println("hello5");
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a1Cl9XGR-1600842737069)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200622094307884.png)]
选择结构
if单选择结构
我们很多时候需要去判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用if语句来表示。
语法:
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}
package com.wjq.struct;
import java.util.Scanner;
public class IfDemo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String s = scanner.nextLine();
//equals:判断字符窜是否相等
if (s.equals("Hello")){
System.out.println(s);
}
System.out.println("End");
scanner.close();
}
}
if双选择结构
语法:
if(布尔表达式){
//如果布尔表达式的值为true
}else{
//如果布尔表达式的值为false
}
package com.wjq.struct;
import java.util.Scanner;
public class IfDemo02 {
public static void main(String[] args) {
//考试分数大于60分就是及格,小于60就是不及格
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score>=60){
System.out.println("恭喜你,你的成绩合格");
}else{
System.out.println("很遗憾,你的成绩不及格");
}
scanner.close();
}
}
if多选择结构
语法:
if(布尔表达式1){
//如果布尔表达式1的值为true,执行代码
}else if(布尔表达式2){
//如果布尔表达式2的值为true,执行代码
}else if(布尔表达式3){
//如果布尔表达式3的值为true,执行代码
}else{
//如果以上布尔表达式都不为true,执行代码
}
package com.wjq.struct;
import java.util.Scanner;
public class IfDemo03 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
/*
if 语句至多有 1 个 else 语句,else语句在所有的else if 语句之后。
if 语句可以有若干个 else if 语句,它们必须在else语句之前
一旦其中一个 else if 语句检测为 true,其他的else if 以及 else 语句都将跳过执行
*/
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if (score == 100) {
System.out.println("恭喜你,你的成绩为满分");
} else if (score < 100 && score >= 90) {
System.out.println("你的成绩为A");
} else if (score < 90 && score >= 80) {
System.out.println("你的成绩为B");
} else if (score < 80 && score >= 70) {
System.out.println("你的成绩为C");
}else if (score<70 && score>=60){
System.out.println("你的成绩为D");
}else if (score<60 && score>=0) {
System.out.println("对不起,你的成绩不及格");
}else{
System.out.println("输入的成绩不合法");
}
scanner.close();
}
}
嵌套的if结构
使用嵌套的if…else语句是合法的。可以在另一个 if 或者 else if 语句中使用 if 或者 else if 语句。
语法:
if(布尔表达式1){
//如果布尔表达式1的值为true,执行代码
if(布尔表达式2){
//如果布尔表达式2的值为true,执行代码
}
}
应用:如何快速查找一个1-100的数字? -->二分法,1-50,50-100嵌套
switch多选择结构
多选择结构还有一个实现方式就是switch case 语句
switch case 语句判断一个变量与一系列值中某个值是否相等,每一个值称之为一个分支。
switch语句中的变量类型可以是:
- byte、short、int或char
- 从Java SE 7开始
- switch 支持字符串 String 类型了*
- 同时 case 标签必须为字符串常量或字面变量
package com.wjq.struct;
public class SwitchDemo01 {
public static void main(String[] args) {
//case 穿透 //switch 匹配一个具体值
char grade = 'B';
switch (grade){
case 'A':
System.out.println("优秀");
break;//可选
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("及格");
break;
case 'D':
System.out.println("再接再厉");
break;
case 'E':
System.out.println("挂科");
break;
default:
System.out.println("未知等级");
}
}
}
- switch 支持字符串 String 类型了*
- 同时 case 标签必须为字符串常量或字面变量
package com.wjq.struct;
public class SwitchDemo02 {
public static void main(String[] args) {
String name = "狂神";
switch (name){
case "秦疆":
System.out.println("秦疆");
break;
case "狂神":
System.out.println("狂神");
break;
default:
System.out.println("弄啥嘞!");
}
}
}
循环结构
while循环 ---->先判断后执行!
do…while循环 ---->先执行后判断! do…while总是保证循环体会被至少执行一次!
for循环
在JAva5中引入了一种主要用于数组的增强型for循环
while循环
while是最基本的循环,它的结构为:
while( 布尔表达式 ){
//循环内容
}
- 只要布尔表达式为true,循环就会一直执行下去
- 我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环。
- 少部分情况需要循环一直执行,比如服务器的请求接听等
- 循环条件一直为true就会造成无限循环【死循环】,我们正常的业务编程中应该尽量避免死循环,会影响程序性能或者造成程序卡死崩溃。
package com.wjq.struct;
public class WhileDemo01 {
public static void main(String[] args) {
//输出1~100
int i= 0;
while(i<100){
i++;
System.out.println(i);
}
}
}
- 思考?:计算1+2+3+4+…+100=?
package com.wjq.struct;
public class WhileDemo03 {
public static void main(String[] args) {
//计算1+2+3+4+...+100=?
//(首项+尾项)*项数 /2
int i = 0;
int sum = 0;
while (i<=100){
sum = sum + i;
i++;
}
System.out.println(sum);
}
}
do…while循环
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while循环 和 while循环相似,不同的是,do…while循环至少会循环一次
do{
//代码语句
}while(布尔表达式);
package com.wjq.struct;
public class DoWhileDemo01 {
public static void main(String[] args) {
int i = 0;
int sum = 0;
do {
sum = sum+i;
i++;
}while(i<=100);
System.out.println(sum);
}
}
while循环 和 do…while循环对比:
package com.wjq.struct;
public class DoWhileDemo02 {
public static void main(String[] args) {
int a = 0;
while (a<0){
System.out.println(a);
a++;
}
System.out.println("============================");
do {
System.out.println(a);
a++;
}while (a<0);
}
}
For循环(**important)
- 虽然所有循环结构都可以用while 或 do…while表示,但Java提供了另一种语句——for循环,使一些循环结构变得更加简单。
- for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构
- for循环执行的次数是在执行前就确定的。
语法:
for(初始化; 布尔表达式; 更新){
//代码语句
}
package com.wjq.struct;
public class ForDemo01 {
public static void main(String[] args) {
int a = 1; //初始化条件
while(a<=100){//条件判断
System.out.println(a);
a+=2; //迭代
}
System.out.println("while循环结束");
//初始化值; 条件判断; 迭代
for (int i = 1; i<=100; i++){
System.out.println(i);
}
//快捷生成:100.for
for (int i = 0; i < 100; i++) {
}
System.out.println("for循环结束!");
/*
关于for循环的几点说明:
最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
然后,检测布尔表达式的值。如果为true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句
执行一次循环后,更新循环控制变量(迭代因子控制环变量的增减)
再次检测布尔表达式,循环执行上面的过程。
*/
//死循环
for (; ; ) {
}
}
}
练习1:计算0到100之间的奇数和偶数的和
package com.wjq.struct;
public class ForDemo02 {
public static void main(String[] args) {
//练习1:计算0到100之间的奇数和偶数的和
int oddSum = 0; //奇数和
int evenSum = 0; //偶数和
for (int i = 0; i <=100; i++) {
if(i%2!=0){ //奇数
oddSum+=i;
}else{ //偶数
evenSum+=i;
}
}
System.out.println("奇数的和:"+oddSum);
System.out.println("偶数的和:"+evenSum);
}
}
练习2:用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
package com.wjq.struct;
public class ForDemo03 {
public static void main(String[] args) {
//用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
for (int i = 0; i <= 1000; i++) {
if (i%5==0){
System.out.print(i+"\t");
}
if (i%(5*3)==0){ //换行
System.out.println();
//System.out.print("\n");
}
}
//println 输出完会换行
//print 输出完不会换行
}
}
练习3:打印九九乘法表
package com.wjq.struct;
public class ForDemo04 {
public static void main(String[] args) {
//打印九九乘法表
//1.我们先打印第一列,应该都会
//2.我们把固定的1再用一个循环包起来
//3.去掉重复项,i<=j
//4.调整样式
for (int j = 1; j <= 9; j++) {
for (int i = 1; i <= j; i++) {
System.out.print(j+"*"+i+"="+(j*i) + "\t");
}
System.out.println();
}
}
}
增强for循环
这里先见一面,后续在数组重点使用
Java5中引入了一种主要用于数组或集合的增强型for循环
语法:
for(声明语句 : 表达式){
//代码句子
}
**声明语句:**声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此时数组元素的值相等。
表达式: 表达式是要访问的数组名,或者是返回值为数组的方法。
package com.wjq.struct;
public class ForDemo05 {
public static void main(String[] args) {
int[] numbers = {10,20,30,40,50}; //定义了一个数组
for( int i = 0; i<5 ;i++){
System.out.println(numbers[i]);
}
System.out.println("===========================");
//遍历数组的元素
for (int x : numbers){
System.out.println(x);
}
}
}
break continue
- break在执行任何循环语句的主体部分,均可用break控制循环的流程。break用于强制退出循环,不执行循环语句中剩余的语句。(break语句也在switch语句中使用)
package com.wjq.struct;
public class BreakDemo {
public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
System.out.println(i);
if (i==30){
break;
}
}
}
}
- continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
package com.wjq.struct;
public class ContinueDemo {
public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
if (i%10==0){
System.out.println();
continue;
}
System.out.println(i);
}
}
}
关于goto关键字:
- goto关键字很早就在程序设计语言中出现。尽管goto仍是java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在break和continue这两个关键字上,我们仍然能看出一些goto的影子——带标签的break和continue。
- “标签”是指后面跟一个冒号的标识符,例如:label:
- 对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于break和continue关键字通常只中断当前循环,但若随标签使用,它们就会中断到存在标签的地方。
package com.wjq.struct;
public class LabelDemo {
public static void main(String[] args) {
//打印101——150之间的所有质数
//质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
int count = 0;
//不建议使用!!!
outer:for (int i = 101; i < 150; i++) {
for (int j = 2; j<i/2; j++){
if(i % j==0){
continue outer;
}
}
System.out.print(i+" ");
}
}
}
练习题
打印三角形
package com.wjq.struct;
public class TestDemo {
public static void main(String[] args) {
//打印三角形 5行
//先打印一个倒三角,在反过来打印半个正三角,最后再打印另外半个三角。
for (int i = 1; i <= 5; i++) {
for (int j = 5; j >= i; j--) {
System.out.print(" ");
}
for(int j = 1; j<=i; j++){
System.out.print("*");
}
for(int j = 1; j<i; j++ ){
System.out.print("*");
}
System.out.println();
}
}
}
Java方法
何为方法
- System.out.println(),这是什么? ——>调用系统类里的标准输出对象out中的方法,println()方法
- Java方法是语句的集合,它们在一起执行一个功能
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或对象中
- 方法在程序中被创建,在其他地方被引用
- 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样利于后期的扩展。
package com.wjq.method;
public class Demo01 {
//main方法,void是方法的返回值类型
public static void main(String[] args) { //main方法
int sum = add(1, 2);
System.out.println(sum);
}
//加法
public static int add(int a,int b){
return a+b;
}
}
package com.wjq.method;
public class Demo01 {
//main方法,void是方法的返回值类型,void是返回空
public static void main(String[] args) { //main方法
test();
}
//测试方法
public static void test() {
//用while或for循环输出1-1000之间能被5整除的数,并且每行输出3个
for (int i = 0; i <= 1000; i++) {
if (i % 5 == 0) {
System.out.print(i + "\t");
}
if (i % (5 * 3) == 0) { //换行
System.out.println();
//System.out.print("\n");
}
}
}
}
方法的定义
-
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含一下语法:
-
**方法包含一个方法头和一个方法体。**下面是一个方法的所有的部分:
- **修饰符:**这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
- **返回值类型:**方法可能会返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
- **方法名:**是方法的实际名称。方法名和参数表共同构成方法签名。
- **参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- **形式参数:**在方法被调用时用于接收外界输入的数据。
- **实参:**调用方法时实际传给方法的数据。
- **方法体:**方法体包含具体的语句,定义该方法的功能。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MB2UtgjN-1600842737071)(C:\Users\wjq913\AppData\Roaming\Typora\typora-user-images\image-20200716185353768.png)]
package com.wjq.method; public class Demo02 { public static void main(String[] args) { int max = max(10, 10); System.out.println(max); } //比大小方法 // 修饰符 返回值类型 方法名(形式参数) public static int max(int num1,int num2){ int result = 0; if (num1 == num2){ System.out.println("num1==num2"); } return 0; //终止方法 if (num1>num2){ result = num1; }else{ result = num2; } return result; } }
方法的调用
- 调用方法:对象名.方法名(实参列表)
- Java方法支持两种调用方法的方式,根据方法是否返回值来选择。
- 当方法返回一个值的时候,方法调用常被当作一个值。例如:
int large = max(30,40);
- 如果方法返回值是void,方法调用一定是一条语句
System.out.println("Hello,Kuangsgen!");
- 拓展: 值传递(JAVA) 和 引用传递
方法的重载*
- 重载就是装在一个类中,有相同的函数名称,但形参不同的函数。
- 方法重载的规则:
- 方法名称必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回值可以相同也可以不同
- 仅仅返回类型不同不足以成为方法的重载
- 现实理论:
- 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
package com.wjq.method;
public class Demo02 {
public static void main(String[] args) {
int max = max(10, 10);
System.out.println(max);
}
//比大小方法
// 修饰符 返回值类型 方法名(形式参数)
public static double max(double num1,double num2){
double result = 0;
if (num1 == num2){
System.out.println("num1==num2");
return 0; //终止方法
}
if (num1>num2){
result = num1;
}else{
result = num2;
}
return result;
}
//比大小
public static int max(int num1,int num2){
int result = 0;
if (num1 == num2){
System.out.println("num1==num2");
return 0; //终止方法
}
if (num1>num2){
result = num1;
}else{
result = num2;
}
return result;
}
}
public class Demo02Test {
public static void main(String[] args) {
//int sum = add(10,20);
int sum = add(10,20,30);
System.out.println(sum);
}
public static int add(int a,int b){
return a+b;
}
public static int add(int a,int b,int c){
return a+b+c;
}
}
命令行传参
- 有时候希望运行一个程序时再给它传递消息。这就要靠传递命令行参数给main()函数实现。
package com.wjq.method;
public class Demo03 {
public static void main(String[] args) {
//args.length 数组长度
for (int i = 0; i < args.length; i++) {
System.out.println("args["+i+"]:"+args[i]);
}
}
}
可变参数
- JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)。
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
package com.wjq.method;
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
demo04.test(1,2,3,4,5,6);
}
/*重载非常麻烦
public void method(){}
public void method(int i){}
public void method(int i,int i2){}
public void method(int i,double i2){}
*/
//用可变参数代替(不定项)
public void test(int x , int... i){
System.out.println(x);
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
}
}
package com.wjq.method;
public class Demo04Test {
public static void main(String[] args) {
//调用可变参数的方法
printMax(34,3,3,2,56.5);
printMax(new double[]{1,2,3});
}
public static void printMax(double... numbers){
if (numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序!
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > result){
result = numbers[i];
}
System.out.println("The max value is" + result);
}
}
}
递归***
- A方法调用B方法,很容易理解(eg:main方法调用其他方法)
- 递归就是:A方法调用A方法! 就是自己调用自己
- 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可描述出解题过程所需要的多次重复计算,大大减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
- 递归结构包括两个部分:
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
package com.wjq.method;
public class Demo05 {
//递归思想
public static void main(String[] args) {
System.out.println("阶乘是:"+f(5));
}
//阶乘方法
//1!=1
//2!=2*1
//3!=3*2*1
//4!=4*3*2*1
//5!=5*4*3*2*1
//n=2 2*f(1)
//n=3 3*f(2)*f(1)
public static int f(int n){
if (n == 1){
return 1;
}else{
return n*f(n-1);
}
}
}
练习
Java数组
数组的定义
- 数组是相同类型数据的有序集合。
- 数组描述的是相同类型的若干数据,按照一定的先后次序排列组合而成。
- 其中,每一个数组称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
数组的声明创建
-
首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
dataType[] arrayRefVar; //首选方法 或 dataType arrayRefVar[];
-
Java语言使用new操作符来创建数组,语法如下:
dataType[] arrayRefVar = new dataType[arraySize];
- 数组的元素是通过索引访问的,数组索引从0开始。
- 获取数组的长度:arrays.length
package com.wjq.array;
public class ArrayDemo01 {
public static void main(String[] args) {
//变量的类型 变量的名字 = 变量的值;
int[] nums;//1.定义,声明一个数组
nums = new int[10]; //2.创建一个数组,这里面可以存放10个int类型的数字
//3.给数组元素赋值
nums [0] = 1;
nums [1] = 2;
nums [2] = 3;
nums [3] = 4;
nums [4] = 5;
nums [5] = 6;
nums [6] = 7;
nums [7] = 8;
nums [8] = 9;
nums [9] = 10;
System.out.println(nums[9]);
//计算所有元素的和
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum = sum+nums[i];
}
System.out.println("总和为:"+sum);
}
}
内存分析
package com.wjq.array;
public class Man {
public static void main(String[] args) {
//静态初始化: 创建 + 赋值
int[] a= {1,2,3,4,5,6,7,8};
Man [] mans = {new Man(),new Man()};
System.out.println(a[0]);
//动态初始化: 包含默认初始化
int [] b = new int[10];
b[0] = 10;
System.out.println(b[0]);
System.out.println(b[1]);
System.out.println(b[2]);
System.out.println(b[3]);
System.out.println(b[4]);
}
}
数组的基本特点
- 其长度是确定的,数组一旦被创建,它的大小是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中。
数组边界
-
下标的合法区间: [0,length-1],如果越界就会报错:
pblic static void main(String[] args){ int[] a = new int[2]; System.out.println(a[2]); }
-
ArraryIndexOutOfBoundsException: 数组下标越界异常!
-
小结:
- 数组是相同数据类型(数据类型可以为任意类型)的有序集合。
- 数组也是对象。数组元素相当于对象的成员变量。
- 数组长度是确定的,不可变的。如果越界,则报:ArrayIndexOutOfBounds
数组使用
package com.wjq.array;
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
// for (int array : arrays) {
// System.out.println(array);
// }
//}
//printArray(arrays);
int[] reverse = reverse(arrays);
printArray(reverse);
}
//反转数组
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
//反转的操作
for (int i=0,j=result.length-1; i < arrays.length; i++,j--) {
result[j] = arrays[i];
}
return result;
}
//打印数组元素
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
}
多维数组
- 多维数组可以看做是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
- 二维数组
int[][] a = new int[2][5];
package com.wjq.array;
public class ArrayDemo05 {
public static void main(String[] args) {
//4行2列
/**
* 1 2 array[0]
* 3 4 array[1]
* 5 6 array[2]
* 7 8 array[3]
*/
int [][] array = {{1,2},{3,4},{5,6},{7,8}};
//printArray(array[0]);
//System.out.println(array[0][0]);
//System.out.println(array[0][1]);
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.println(array[i][j]);
}
}
}
//打印数组元素
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i] + " ");
}
}
}
Arrays 类
-
数组的工具类java.util.Arrays
-
由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本操作。
-
查看JDK帮助文档
-
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而“不用”使用对象来调用(注意是“不用”,而不是“不能”)
-
具有以下常用功能 :
- 给数组赋值: 通过fill方法
- 对数组排序: 通过sort方法,按升序。
- 比较数组: 通过equals 方法比较数组中元素值是否相等。
- 查找数组元素:通过binarySearch方法能对排好的数组进行二分法查找。
package com.wjq.array; import java.util.Arrays; public class ArrayDemo06 { public static void main(String[] args) { int [] a = {1,2,3,4,990,326363,56,21,336,54}; //System.out.println(a); //[I@1540e19d 哈希code //printArray(a); Arrays.sort(a); //对数组进行排序: 升序; //打印数组元素 System.out.println(Arrays.toString(a)); Arrays.fill(a,2,4,0); System.out.println(Arrays.toString(a)); } public static void printArray(int[]a){ for (int i = 0; i < a.length; i++) { if (i==0){ System.out.print("["); } if (i==a.length-1){ System.out.println(a[i]+"]"); }else { System.out.print(a[i] + ", "); } } } }
冒泡排序
- 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!
- 冒泡排序的代码还是相对简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人尽皆知。
- 看到嵌套循环,可以得出这个算法的时间复杂度为O(n2)
- 思考:如何优化?
package com.wjq.array;
import java.util.Arrays;
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a = {1,2,3,4562,56,85,46,96,236,12,11};
int[] sort = sort(a); //调用完我们自己写的排序方法后,返回一个排序后的数组
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置
//2.每一次比较,都会产生出一个最大,或最小的数字;
//3.下一轮,则可以少一次排序1
//4.依次循环,直到结束!
public static int[] sort(int[] array){
//交换时用的临时变量
int temp = 0;
//外层循环,判断我们这个要走多少次;
for (int i=0;i<array.length-1;i++){
boolean flag = false;//优化:通过flag标识位减少没有意义的比较
//内层循环,比较判断两个数,如果第一个数比第二个数大,则交换位置;
for (int j = 0; j < array.length-1-i; j++) {
if (array[j+1]<array[j]){ //从小到大排列
//实现两数进行交换
temp = array[j];
array[j]=array[j+1];
array[j+1] = temp;
flag = true;
}
}
//优化
if (flag==false){
break;
}
}
return array;
}
}
选择排序
import java.util.Arrays;
public class C7 {
public static void main(String[] args) {
//选择排序法
int[] array = {128, 73, 18, 23, 71, 28, 7, 333, 123, 5};
for (int j = 0; j < array.length - 1; j++) {
for (int i = j + 1; i < array.length; i++) {
if (array[j] > array[i]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
/*
* 选择排序法:
* array
*
* 128, 73, 18, 23, 71, 28, 7, 333, 123, 5
* # ^
* |
* i=1
* array[0] pk array[i] 失败
* 128, 73, 18, 23, 71, 28, 7, 333, 123, 5
* ^
* |
* i=2
* array[0] pk array[i] 失败
* 128, 73, 18, 23, 71, 28, 7, 333, 123, 5
* ^ ^ ^ ^
* 128, 73, 18, 23, 71, 28, 7, 333, 123, 5
* # ^
* |
* i=7
* array[0] pk array[i] 成功, 交换
* 333 73, 18, 23, 71, 28, 7, 128 123 5
* # ^ ^
*
*
* i: [0, array.length)
*
* for(int i=1; i<array.length; i++){
* if( array[0] < array[i] ){
* int temp = array[0];
* array[0] = array[i];
* array[i] = temp;
* }
* }
*
* 128, 73, 18, 23, 71, 28, 7, 333, 123, 5
* # ^ ^
* | |
* i=2 i=array.length-1
* for(int i=2; i<array.length; i++){
* if( array[1] < array[i] ){
* int temp = array[1];
* array[1] = array[i];
* array[i] = temp;
* }
* }
* for(int i=3; i<array.length; i++){
* if( array[2] < array[i] ){
* int temp = array[2];
* array[2] = array[i];
* array[i] = temp;
* }
* }
*
* .....
*
* for( int i=array.length-1; i<array.length; i++){
* if( array[array.length-2] < array[i] ){
* int temp = array[array.length-2];
* array[array.length-2] = array[i];
* array[i] = temp;
* }
*
* }
*
*
* 分析:
* j: 0,1,2, ... array.length-2
* start: 1,2,3, .. array.length-1
* x: 0,1,2 ... array.length-2
* for(int i=start; i<array.length; i++){
* if( array[x] < array[i] ){
* int temp = array[x];
* array[x] = array[i];
* array[i] = temp;
* }
* }
*
*
* for(int j=0;j<array.length-1; j++){
* for(int i=j+1; i<array.length; i++){
* if( array[j] < array[i] ){
* int temp = array[j];
* array[j] = array[i];
* array[i] = temp;
* }
* }
* }
*
*
* */
}
稀疏数组
- 需求:编写五子棋游戏中,有存盘退出和续上盘的功能。
- 分析问题:因为该二维数组的很多值是默认0,因此记录了很多没有意义的数据。
- 解决办法:稀疏数组
稀疏数组介绍:
- 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
- 稀疏数组的处理方式是:
- 记录数组一共有几行几列,有多少个不同值
- 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
- 如下图:左边是原始数组,右边是稀疏数组
package com.wjq.array;
public class ArrayDemo08 {
public static void main(String[] args) {
//1.创建一个二维数组11*11 0:没有棋子, 1:黑棋 2:白棋
int [][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始数组:
System.out.println("输出原始的数组:");
// for (int i = 0; i < array1.length; i++) {
// for (int j = 0; j < array1[i].length; j++) {
// System.out.print(array1[i][j]+"\t");
// }
// System.out.println();
// }
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
System.out.println("=========================================");
//转换为稀疏数组保存
//获取有效值的个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数:"+sum);
//2.创建一个稀疏数组
int [][] array2 = new int[sum+1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历二维数组,将非零的值存放到稀疏数组
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j <array1[i].length ; j++) {
if (array1[i][j]!=0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组
System.out.println("稀疏数组为:");
for (int i = 0; i <array2.length ; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1]+"\t"
+array2[i][2]+"\t");
}
System.out.println("=========================================");
System.out.println("还原");
//1.读取稀疏数组
int [][] array3 = new int[array2[0][0]][array2[0][1]];
//2.给其中的元素还原值
for (int i = 1; i <array2.length ; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.打印还原
System.out.println("输出还原的数组:");
for (int[] ints : array3) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}
面向对象OOP
Java的核心思想就是OOP
初识面向对象
面向过程 & 面向对象
-
面向过程思想
- 步骤清晰简单,第一步做什么,第二部做什么…
- 面对过程适合处理一些较为简单的问题
-
面向对象思想
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
-
对于描述复杂的事物,伪类从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
什么是面向对象
- 面向对象编程(Object-Oriented Programming,OPP)
- 本质:以类的方式组织代码,以对象的组织(封装)数据。
- 抽象
- 三大特征
- 封装
- 继承
- 多态
- 从认识论角度考虑是先有对象后有类。 对象,就是具体的事物。 类,是抽象的,是对对象的抽象
- 从代码运行角度考虑是先有类后有对象。类是对象的模板。
方法回顾和加深
方法的定义
- 修饰符
- 返回类型
- break和return的区别
- break是跳出switch,跳出循环
- return是方法的结束
- 方法名:注意规范----见名知意
- 参数列表:(参数类型,参数名) …->可变长参数
- 异常抛出
方法的调用
- 静态方法:加static后可以直接通过 类名 .方法名(Student.say();) 在另一个程序的main方法中调用
-
非静态方法:
无法直接通过 类名 .方法名(Student.say();) 来调用
**要通过实例化这个类 new**
- 形参和实参
package com.oop.demo01;
public class Demo03 {
public static void main(String[] args) {
//实际参数和形式参数的类型要对应!
//实际参数
int add = Demo03.add(2, 3);
System.out.println(add);
}
//形式参数
public static int add(int a,int b){
return a+b;
}
}
- 值传递和引用传递
package com.oop.demo01;
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a); //结果为1
Demo04.change(a);
System.out.println(a); //结果为1
}
//返回值为空
public static void change(int a){
a=10;
}
}
package com.oop.demo01;
//引用传递:传递一个对象,本质还是值传递
// 对象 , 内存!
public class Demo05 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); //null
Demo05.change(person);
System.out.println(person.name); //秦疆
}
public static void change(Person person){
//person是一个对象: 指向的是 ---> Person person = new Person(); 这是一个具体的人,可以改变属性!
person.name = "秦疆";
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name; //默认值为null
}
- this关键字
对象的创建分析
类与对象的关系
- 类是一种抽象的数据类型,它是对某一类事物整体的描述/定义,但是并不能代表某一具体的事物。
- 动物、植物、手机、电脑…
- Person类、Pet类、Car类等,这些都是用来描述/定义某一类具体的事物应该具备的特点和行为
- 对象是抽象概念的具体实例
- 张三就是人的一个具体实例,张三家里的旺财就是狗的一个具体实例
- 能够体现出特点,展现出功能的是具体的实例,而不是一个抽象的概念
创建与初始化对象
- 使用 new 关键字创建对象
- 使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
package com.oop.demo02;
//一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
//类 :抽象的,实例化
//类实例化后会返回一个自己的对象!
//student对象就是一个Student类的具体实例!
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name = "小明";
xiaoming.age = 21;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xh.name = "小红";
xh.age = 3;
System.out.println(xh.name);
System.out.println(xh.age);
}
}
package com.oop.demo02;
//学生类
public class Student {
//属性: 字段
String name;
int age;
//方法
public void study(){
System.out.println(this.name+"在学习。。。");
}
}
- 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
- 1.必须和类名字相同
- 2.必须没有返回类型,也不能写void
- 构造器必须要掌握
package com.oop.demo02;
//.java-->.class
public class Person {
//一个类即使什么都不写,它也会存在一个默认构造器
//显示定义的构造器
String name;
//实例化初始值
//1.使用new关键字,本质是在调用构造器
//2.构造器是用来初始化值的
public Person() {
}
//有参构造器:一旦定义了有参构造器,无参构造器就必须显示定义
public Person(String name){
this.name = name;
}
//alt+insert 快捷生成有参构造器
//生成无参构造器: 点SelectNull
}
/**
* public static void main(String[] args) {
*
* //实例化了一个对象
* Person person = new Person("秦疆");
* System.out.println(person.name);
* }
*
* 构造器:
* 1.和类名相同
* 2.没有返回值
* 作用:
* 1.new 本质是在调用构造方法
* 2.初始化对象的值
* 注意点:
* 1.定义了无参构造器之后,如果想使用无惨构造器,显示的定义一个无惨构造器
*
* Alt+Insert
* 1.快捷生成各种方法
*
* this. =
*/
创建对象内存分析
类与对象小结
/**
*1.类与对象
类是一个模板:抽象的,对象是一个具体的实例
*2.方法
定义,调用!
*3.对象的引用:
引用类型: 基本类型(8)
对象是通过引用来操作的: 栈--->堆(地址)
*4.属性:字段Filed 成员变量
默认初始化:
数字:0,0.0
char: u0000
boolean: false
引用类型: null
修饰符 属性类型 属性名 = 属性值!
*5.对象的创建和使用
1.必须使用new关键字创建对象,构造器 Preson wjq = new Person();
2.对象的属性 wjq.name;
3.对象的方法 wjq.sleep();
*6.类:
静态的属性 属性
动态的行为 方法
封装、继承、多态
*/
面向对象三大特征***
封装
- 该露的露,该藏的藏
- 程序设计讲究**“高内聚,低耦合”**。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
- 封装(数据的隐藏)
- 通常,应禁止直接访问一个对象数据的实际表示,而应通过操作接口来访问,这称为信息隐藏。
- 记住这句话: 属性私有,get/set
package com.oop;
import com.oop.demo04.Student;
/**
* 封装:
* 1.提高程序安全性,保护数据
* 2.隐藏代码实现细节
* 3.统一接口
* 4.系统可维护性增加了
*/
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("秦疆");
System.out.println(s1.getName());
s1.setAge(999); //不合法的
System.out.println(s1.getAge());
}
}
package com.oop.demo04;
//类 private 属性私有
public class Student {
//名字、学号、性别、
//学习()、睡觉()
private String name;
private int id;
private char sex;
private int age;
//提供一些可以操作这个属性的方法!
//提供一些public的get、set方法
//get 获得这个数据
public String getName(){
return this.name;
}
//set 给这个数据设置值
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120 || age<0){
System.out.println("输入的年龄不合法");
}else{
this.age = age;
}
}
}
继承
- 继承本质是对某一批类的抽象,从而实现对现实世界更好的建模。
- extends 的意思是“扩展”。子类是父类的扩展。
- Java中类只有单继承 ,没有多继承!
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
- 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示。
- 子类和父类之间,从意义上讲应该具有 “is a” 的关系。
- object类
package com.oop.demo05;
//在java中,所有的类,都默认直接或间接继承Object
public class Person extends Object{
//public
//protected
//default
//private
private int money = 10_0000_0000;
public void say() {
System.out.println("说了一句话");
}
public int getMoney() {
return money;
}
public void setMoney(int money) {
this.money = money;
}
}
package com.oop.demo05;
//Student is 人: 派生类,子类
//子类继承父类,就会拥有父类的全部方法
public class Student extends Person{
//Ctrl + H :查看继承树
}
package com.oop.demo05;
//Teacher is 人: 派生类,子类
public class Teacher extends Person{
}
package com.oop.demo05;
import com.oop.demo05.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.getMoney());
Person person = new Person();
person.getClass();
}
}
- super
package com.oop.demo05;
//在java中,所有的类,都默认直接或间接继承Object
public class Person /*extends Object*/{
public Person(){
System.out.println("Person无惨构造执行");
}
protected String name = "kuangshen";
//私有的东西无法被继承!
public void print(){
System.out.println("Person");
}
}
package com.oop.demo05;
//Student is 人: 派生类,子类
//子类继承父类,就会拥有父类的全部方法
public class Student extends Person{
public Student() {
//隐藏代码:调用了父类的无参构造器
//调用父类构造器,必须要在子类构造器的第一行
super();
System.out.println("Student无参构造执行");
}
private String name = "qinjjiang";
public void print(){
System.out.println("Student");
}
public void test1(){
print();
this.print();
super.print();
}
public void test(String name){
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}
package com.oop.demo05;
import com.oop.demo05.Student;
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.test("秦疆");
student.test1();
}
}
super注意点:
1.super调用父类的构造方法,必须在构造方法的第一个
2.super 必须只能出现在子类的方法或者构造方法中!
3.super 和 this不能同时调用构造方法!
VS this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的应用
前提:
this:没有继承也可以使用
super:只能在继承条件才能调用
构造方法:
this(): 本类的构造
super(): 父类的构造!
- 方法重写
package com.oop.demo05;
//重写都是方法的重写,和属性无关
public class B{
public void test(){
System.out.println("B=>test()");
}
}
package com.oop.demo05;
//继承
public class A extends B{
@Override //注解:有功能的注释!
public void test() {
System.out.println("a=>test()");
}
}
package com.oop.demo05;
//在java中,所有的类,都默认直接或间接继承Object
public class Person /*extends Object*/{
public Person(){
System.out.println("Person无惨构造执行");
}
protected String name = "kuangshen";
//私有的东西无法被继承!
public void print(){
System.out.println("Person");
}
}
重写:需要有继承关系,子类重写父类的方法!
1.方法名必须相同
2.参数列表必须相同
3.修饰符:范围可以扩大: public-->protected-->default-->private
4.抛出异常:范围,可以被缩小,但不能扩大; ClassNotFoundException-->Exception(大)
重写,子类的方法和父类必须要一致;方法体不同
为什么需要重写:
1.父类的功能,子类不一定需要,或者不一定满足
Alt+Insert : override;
多态
-
即同一方法可以根据发送对象的不同而采取多种不同的行为方式
-
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多(父类,有关系的类)
-
多态存在条件:
- 有继承关系
- 子类重写父类方法
- 父类引用子类对象
-
注意:多态是方法的多态,属性没有多态
-
instanceof (类型转换) 引用类型
package com.oop.demo06;
public class Person {
public void run(){
System.out.println("run");
}
}
/**
* 多态注意事项:
* 1.多态是方法的多态,属性没有多态
* 2.父类和子类,有联系 类型转换异常
* 3.存在条件:
* 继承关系,方法需要重写,
* 父类引用指向子类对象 Father f1 = new Son();
*
* 1.static 方法,属于类,它不属于实例,无法重写
* 2.final : 常量
* 3.private 方法;
*/
package com.oop.demo06;
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
package com.oop.demo06;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型就不确定了: 父类的引用指向子类
//Student 能调用的方法都是自己的或是继承父类的
//Person 父类型,可以指向子类,但是不能调用子类独有的方法
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
//s2.eat(); //子类重写了父类的方法,执行子类的方法
s1.run();
s2.run();
s1.eat();
}
}
- instanceof
package com.oop.demo06;
public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.demo06;
public class Student extends Person{
public void go(){
System.out.println("go");
}
}
package com.oop.demo06;
public class Teacher extends Person{
}
package com.oop.demo06;
import com.oop.demo06.Person;
import com.oop.demo06.Student;
public class Application {
public static void main(String[] args) {
//类型之间的转化: 父 子
//高 低
//Student将这个Person对象转换为Student类型,这样就可以使用Student类型方法了!
Person obj = new Student();
((Student)obj).go();
Student student = new Student();
student.go();
//子类转换为父类,可能丢失一些自己本来的方法
Person person = student;
}
}
/**
* 1.父类引用指向子类对象
* 2.把子类转换成父类,向上转型;可以直接转
* 3.把父类转换成子类,向下转型;需要强制转换
* 4.方便方法调用,减少重复的代码!简洁
*
* 抽象: 封装,继承,多态! 抽象类,接口
*/
/**
* //Object > String
* //Object > Person > Student
* //Object > Person > Teacher
*
* //System.out.println(x instanceof y); //能不能编译通过!看x和y是否存在父子关系
*
* // Object object = new Student();
* // System.out.println(object instanceof Student); //true
* // System.out.println(object instanceof Person); //true
* // System.out.println(object instanceof Object); //true
* // System.out.println(object instanceof Teacher); //false
* // System.out.println(object instanceof String); //false
* // System.out.println("========================================");
* //
* // Person person = new Student();
* // System.out.println(person instanceof Student); //true
* // System.out.println(person instanceof Person); //true
* // System.out.println(person instanceof Object); //true
* // System.out.println(person instanceof Teacher); //false
* // //System.out.println(person instanceof String); //编译报错!
* // System.out.println("========================================");
* //
* // Student student = new Student();
* // System.out.println(student instanceof Student); //true
* // System.out.println(student instanceof Person); //true
* // System.out.println(student instanceof Object); //true
* //System.out.println(student instanceof Teacher); //编译报错!
* //System.out.println(person instanceof String); //编译报错!
*/
ststic关键字详解
package com.oop.demo7;
public class Person {
//2.赋初始值~
{
//这是代码块 (匿名代码块)
System.out.println("匿名代码块");
}
//1.static 只执行一次~
static {
//静态代码块
System.out.println("静态代码块");
}
//3.
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("===========================");
Person person2 = new Person();
}
}
package com.oop.demo7;
//static
public class Student {
private static int age; //静态变量 多线程!
private double score; //非静态变量
public void run(){
go();
}
public static void go(){
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(Student.age); //静态变量直接类名.变量
System.out.println(s1.age);
System.out.println(s1.score);
new Student().run();
go();
}
}
package com.oop.demo7;
import static java.lang.Math.random; //静态导入包~
public class Test {
public static void main(String[] args) {
System.out.println(random()); //产生一个随机数
}
}
抽象类和接口
抽象类
- abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类
- 抽象类中可以没有抽象方法,但是抽象方法的类一定要声明为抽象类
- 抽象类,不能使用new关键字来创建对象,它是用来让子类继承的
- 抽象方法,只有方法的声明,没有方法的实现, 它是用来让子类实现的
- 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
package com.oop.demo08;
//abstract 抽象类 :类 extends: 单继承 (接口可以实现多继承)
public abstract class Action {
//约束~ 有人帮忙实现
//abstract ,抽象方法,只有方法名字,没有方法的实现!
public abstract void doSomething();
//1.不能 new 抽象类,只能靠子类去实现它:约束!
//2.抽象类中可以写普通的方法~
//3.抽象方法必须在抽象类中~
//抽象的抽象:约束~
//思考题? 不能new, 那抽象类存在构造器吗
//抽象类存在的意义 -->抽象出来,提高开发效率
}
package com.oop.demo08;
//抽象类的所有方法,继承了它的子类都必须要实现它的方法,除非子类也是abstract
public class A extends Action{
@Override
public void doSomething() {
}
}
接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象)
package com.oop.demo09;
//抽象的思维~Java
//interface 定义的关键字 , 接口都需要有实现类
public interface UserService {
//接口中的所有定义其实都是抽象的 public abstract
/*public abstract*/ void run(String name);
//常量~public static final
/*public static final*/int AGE = 99;
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package com.oop.demo09;
public interface TimeService {
void timer();
}
package com.oop.demo09;
//抽象类:extends~
//类可以实现接口,implements 接口
//实现了接口的类,就需要重写接口中的方法
//多继承~利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{
@Override
public void run(String name) {
}
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
接口作用:
1.约束
2.定义一些方法,让不同的人实现~
3.public abstract
4.public static final
5.接口不能被实例化~,接口中没有构造方法~
6.implements可以实现多个接口
7.必须要重写接口中的方法
内部类及OOP实战
内部类
- 内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对于A类来说就称为内部类,而A类相对B类来说就是外部类了。
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
package com.oop.demo10;
public class Outer {
private int id = 100000000;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性~、方法
public void getID(){
System.out.println(id);
}
}
//方法里也可以写类-->局部内部类
public void method(){
class Inner1{
public void in(){
}
}
}
}
//一个java类中可以有多个class类,但是只能有一个public class
class A{
public static void main(String[] args) {
}
}
package com.oop.demo10;
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
//通过这个外部类来实例化内部类~
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getID();
}
}
package com.oop.demo10;
public class Test {
public static void main(String[] args) {
Apple apple = new Apple();
apple.eat();
//没有名字初始化类,不用将实例保存到变量中
new Apple().eat();
UserService userService = new UserService() {
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("eating");
}
}
interface UserService{
void hello();
}
异常
什么是异常
- 实际工作中,遇到的情况不可能是完美的。比如:写的某个模块,用户输入不一定符合你的要求、你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,你要读取数据库的数据,数据可能是空的。程序跑着跑着,内存或硬盘可能满了…
- 软件运行过程中,非常可能遇到异常:Exception,意思是例外。这些例外情况,叫异常。
- 异常指程序运行过程中出现的不期而至的各种情况,如:文件找不到、网络连接失败、非法参数等。
- 异常发生在程序运行期间,它影响了正常的程序执行流程。
分类:
- **检查性异常:**最具代表的检查性异常是用户错误或者问题引起的异常,这是程序 无法预见的。例如,要打开一个不存在的问件时,一个异常就发生了,这些异常在编译时不能被简单的忽略。
- **运行时异常:**运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
- **错误Error:**错误不是异常,而是脱离程序员控制的问题。错误在代码中常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到。
Error:
- Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
- Java虚拟机运行错误(Virtual MachineError),当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止;
- 还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。
Exception:
- 在Exception分支中有一个重要的子类RuntimeException(运行时异常)
- ArrayIndexOutOfBoundsException(数组下标越界)
- NullPointerException(空指针异常)
- ArithmeticException(算数异常)
- MissingResourceException(丢失资源)
- ClassNotFoundException(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获,也可以不处理。
- 这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
Error和Exception的区别:
- Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止线程;
- Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。
异常体系结构
Java异常处理机制
- 抛出异常
- 捕获异常
- 异常处理五个关键字
- try、catch、finally、throw、throws
package com.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {
new Test().test(1,0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
//假设这个方法中处理不了这个异常。
// public void test(int a,int b){
// if (b==0){ // throw throws
// throw new ArithmeticException(); //主动抛出一个异常,一般在方法中使用
// }
// System.out.println(a/b);
// }
//在方法上抛出异常
public void test(int a,int b)throws ArithmeticException {
if (b == 0) { // throw throws
throw new ArithmeticException(); //主动抛出一个异常,一般在方法中使用
}
}
}
/**
* //假设要捕获多个异常,要从小到大捕获
* try { //监控区域
*
* if (b==0){ //主动抛出异常 throw throws
* throw new ArithmeticException(); //主动抛出一个异常
* }
* System.out.println(a/b);
* }catch (Error e){ //catch(想要捕获的异常类型!) 捕获异常 Throwable-->Exception/Error
* System.out.println("程序出现异常:变量b不能为0");
* }catch (Exception e){
* System.out.println("Exception");
* }catch(Throwable e){
* System.out.println("Throwable");
* }finally { //处理善后工作
* System.out.println("finally");
* }
*
* //finally 善后,可以不要finally。 假设IO,资源,关闭
*/
package com.exception;
public class Test2 {
public static void main(String[] args) {
int a = 1;
int b= 0;
//Ctrl+Alt+T:自动生成try/catch
try {
System.out.println(a/b);
} catch (Exception e) {
System.out.println("程序出现异常:变量b不能为0");
e.printStackTrace(); //打印错误的栈信息
}
}
}
自定义异常
- 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
- 在程序中使用自定义异常类,分为以下几步:
- 1.创建自定义异常类。
- 2.在方法中通过throw关键字抛出异常对象。
- 3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获处理;否则在方法的声明处通过throw关键字指明要抛出给方法调用者的异常,继续执行下一步操作。
- 4.在出现异常方法的调用者中捕获并处理异常。
package com.exception.demo02;
//自定义的异常类
public class MyException extends Exception{
//传递数字>10;
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" + "detail=" + detail + '}';
}
}
package com.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为:"+a);
if (a>10){
throw new MyException(a); //抛出
}
System.out.println("ok");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println("MyException=>"+e);
}
}
}
实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避,同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源
JavaSE总结
1,补码
2, 数据类型(8个基本类型)
3, 运算符(…)
4, 流程控制(if-else, switch, for, while)
5, 数组 (创建,遍历,赋值 )
6, 面向对象
- 类定义(属性,方法(setter,getter,toString,其它方法),构造器,(构造器重载)
- 静态方法和静态属性
- 继承
- 抽象类
- 接口
- OOP三大特征的理解
- 内部类
- 代码块(构造块,静态块)
7, String的方法
- 求长度,
- 分割
- 比较
- …
- 正则表达式
- 字符与编码(utf8)
8, 集合
Collection->ArrayList,LinkedList,HashSet,TreeSet
List->ArrayList,LinkedList
Set->HashSet,TreeSet
Map->HashMap,TreeMap
这些接口的常用方法: add, remove, size, put, get
9, IO流
- 理论(输入输出,序列化与反序列化, 编码与解码)
- File类
- (字节流)FileInputStream, FileOutputStream, BufferedInputStream,BufferedOutputStream, DataInputStream/DataOutputStream, ObjectInputStream,ObjectOutputStream
- (字符流)FileReader,FileWriter, BufferedReader,BufferedWriter
- System.in, System.out, System.err
10, 线程
- 理论(进程,线程)
- 创建方式(两种:继承,实现Runnable)
- 线程同步(锁, synchronized)
- 线程池( ExecutorService pool = new ScheduleThreadPool(…) , pool.execute(Runnable) , pool.shutdown() )
11, 网络编程
- 理论(IP,PORT,网络分层)
- TCP编程流程
- UDP编程流程
12, 设计模式
- 单例
- 工厂(静态工厂,实例工厂)
- 装饰者
// }
//在方法上抛出异常
public void test(int a,int b)throws ArithmeticException {
if (b == 0) { // throw throws
throw new ArithmeticException(); //主动抛出一个异常,一般在方法中使用
}
}
}
/**
- //假设要捕获多个异常,要从小到大捕获
-
try { //监控区域
-
if (b==0){ //主动抛出异常 throw throws
-
throw new ArithmeticException(); //主动抛出一个异常
-
}
-
System.out.println(a/b);
-
}catch (Error e){ //catch(想要捕获的异常类型!) 捕获异常 Throwable-->Exception/Error
-
System.out.println("程序出现异常:变量b不能为0");
-
}catch (Exception e){
-
System.out.println("Exception");
-
}catch(Throwable e){
-
System.out.println("Throwable");
-
}finally { //处理善后工作
-
System.out.println("finally");
-
}
-
//finally 善后,可以不要finally。 假设IO,资源,关闭
*/
```java
package com.exception;
public class Test2 {
public static void main(String[] args) {
int a = 1;
int b= 0;
//Ctrl+Alt+T:自动生成try/catch
try {
System.out.println(a/b);
} catch (Exception e) {
System.out.println("程序出现异常:变量b不能为0");
e.printStackTrace(); //打印错误的栈信息
}
}
}
自定义异常
- 使用Java内置的异常类可以描述在编程时出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承Exception类即可。
- 在程序中使用自定义异常类,分为以下几步:
- 1.创建自定义异常类。
- 2.在方法中通过throw关键字抛出异常对象。
- 3.如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获处理;否则在方法的声明处通过throw关键字指明要抛出给方法调用者的异常,继续执行下一步操作。
- 4.在出现异常方法的调用者中捕获并处理异常。
package com.exception.demo02;
//自定义的异常类
public class MyException extends Exception{
//传递数字>10;
private int detail;
public MyException(int a) {
this.detail = a;
}
//toString:异常的打印信息
@Override
public String toString() {
return "MyException{" + "detail=" + detail + '}';
}
}
package com.exception.demo02;
public class Test {
//可能会存在异常的方法
static void test(int a) throws MyException {
System.out.println("传递的参数为:"+a);
if (a>10){
throw new MyException(a); //抛出
}
System.out.println("ok");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyException e) {
System.out.println("MyException=>"+e);
}
}
}
实际应用中的经验总结
- 处理运行时异常时,采用逻辑去合理规避,同时辅助try-catch处理
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会遗漏的异常
- 对于不确定的代码,也可以加上try-catch,处理潜在的异常
- 尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定
- 尽量添加finally语句块去释放占用的资源
JavaSE总结
1,补码
2, 数据类型(8个基本类型)
3, 运算符(…)
4, 流程控制(if-else, switch, for, while)
5, 数组 (创建,遍历,赋值 )
6, 面向对象
- 类定义(属性,方法(setter,getter,toString,其它方法),构造器,(构造器重载)
- 静态方法和静态属性
- 继承
- 抽象类
- 接口
- OOP三大特征的理解
- 内部类
- 代码块(构造块,静态块)
7, String的方法
- 求长度,
- 分割
- 比较
- …
- 正则表达式
- 字符与编码(utf8)
8, 集合
Collection->ArrayList,LinkedList,HashSet,TreeSet
List->ArrayList,LinkedList
Set->HashSet,TreeSet
Map->HashMap,TreeMap
这些接口的常用方法: add, remove, size, put, get
9, IO流
- 理论(输入输出,序列化与反序列化, 编码与解码)
- File类
- (字节流)FileInputStream, FileOutputStream, BufferedInputStream,BufferedOutputStream, DataInputStream/DataOutputStream, ObjectInputStream,ObjectOutputStream
- (字符流)FileReader,FileWriter, BufferedReader,BufferedWriter
- System.in, System.out, System.err
10, 线程
- 理论(进程,线程)
- 创建方式(两种:继承,实现Runnable)
- 线程同步(锁, synchronized)
- 线程池( ExecutorService pool = new ScheduleThreadPool(…) , pool.execute(Runnable) , pool.shutdown() )
11, 网络编程
- 理论(IP,PORT,网络分层)
- TCP编程流程
- UDP编程流程
12, 设计模式
- 单例
- 工厂(静态工厂,实例工厂)
- 装饰者
版权声明:本文标题:JavaSE基础阶段学习笔记 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726764497a1083426.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论