打开CMD的方式
1、开始+系统+命令提示符
2、win + R 输入cmd 打开控制台
3、在任意文件夹下面,按住 shift +鼠标右键点击,在此处打开命令行窗口
4、资源管理器的地址栏前面加上 cmd 路径
管理员方式运行:选择以管理员运行的 方式(可以得到最高权限)
# 盘符切换
C:\Users\XXX> D:
D:\>
# 常看当前目录下的所有文件
D:\> dir
驱动器 D 中的卷没有标签。
卷的序列号是 9E77-CA9C
D:\ 的目录
2019/02/18 16:04 <DIR> 1111
2020/10/17 22:34 <DIR> AE磁盘缓存
2021/03/09 19:35 <DIR> bootstrap4模版
2020/09/18 21:30 <DIR> Eclipse
2021/03/21 20:23 <DIR> javaproject
# 切换目录 cd change directory
cd /d f: # /d 参数实现跨盘符切换
D:\> cd /d f:\bee
f:\bee>
# 返回上级目录
f:\bee>cd ..
f:\>
# 进入同级目录
f:\> cd bee
f:\bee>
f:\bee> cd xunlei
f:\bee\xunlei>
# cls 清理屏幕 (clear screen)
f:\bee\xunlei> cls
exit
ipconfig
calc # 打开计算器
mspaint # 打开画图工具
notepad # 打开记事本
ping www.baidu.com
C:\Users\xxx>cd /d C:\Users\xxx\Desktop
C:\Users\xxx\Desktop>md test # 创建文件夹 md 目录名
C:\Users\xxx\Desktop>cd test # 进入文件夹
C:\Users\xxx\Desktop\test>cd>a.txt # 创建文件 a.txt cd> 文件名
C:\Users\朱鸿君\Desktop\test>del a.txt # 删除文件 del 文件名
C:\Users\朱鸿君\Desktop\test>cd ..
C:\Users\朱鸿君\Desktop>rd test # 移除文件夹 rd 目录名
三高:高可用、高性能、高并发
Java特性和优势:
java三大版本
JDK JRE JVM
安装开发
java -verison
java -verison
helloworld 详解
public class Hello{
public static void main (String[] arges){
System.out.print("hello")
}
}
文件名和类名保持一致
编译:javac Hello.java
生成 class 文件
运行:java Hello
运行class文件
public class HelloWorld {
/**
* 文档注释
* @param args
*/
public static void main(String[] args) {
// 单行注释
System.out.println("hello");
/*
多行注释
*/
}
}
Java 的数据类型分为两大类
什么是字节
位(bit):计算机 内部数据 储存的最小单位,11001100是一个八位二进制
字节(byte):计算机中 数据处理 的基本单位,习惯上用大写B来表示
字符:计算机中使用的字母、数字、字和符号
面试题
整数拓展: 进制 二进制 0b 十进制 八进制 0 十六进制 0x
int i = 10;
int i2= 010; // 8进制 8
int i3 =0x10; // 16进制 0~9 A-F 16
浮点数拓展:
// 浮点数拓展:
// 银行业务 ?
// BigDecimal 数学工具类
// float 有限 离散 舍入误差 大约 接近但不等于
// double
// 最好完全使用浮点数进行比较 最好完全使用浮点数进行比较 最好完全使用浮点数进行比较
float f = 0.1f;// 0.1
double d = 0.1;// 0.1
System.out.println(f==d);// false
float d1 = 23232323f;
float d2 = d1+1;
System.out.println(d1==d2);// true
字符拓展:所有的字符本质还是数字
char c1 = 'a';
char c2 = '中';
System.out.println((int)c1);// 97
System.out.println((int)c2);// 20013
// 所有的字符本质还是数字
// 编码 Unicode:97 = a ;65 = A 2字节 0-65536
char c3 = '\u0061';
System.out.println(c3);//a
转义字符:
// 转义字符
// \t 制表符
// \n 换行
System.out.println("hello\tworld");
字符串:
// 字符串(对象,从内存分析)
String sc = new String("hello");
String sd = new String("hello");
System.out.println(sc==sd); // false
String sc2 = "hello";
String sd2 = "hello";
System.out.println(sc2==sd2);//true
布尔值拓展:
boolean flag= true;
if(flag){} // 老手
if(flag == true){}; // 新手
int i = 128;
byte b= (byte)i;// 内存溢出 -128~127
// 强制转换
System.out.println(i);// 128
System.out.println(b);//-128
int i = 128;
// 自动转换 低--》高
double c =i;
System.out.println(c);// 128.0
char d = 'a';
int e = d+1;
System.out.println(e); // 98
System.out.println((char)e); // b
注意点:
1、不能对布尔类型进行转换
2、不能把对象类型转换成不相干的类型
3、在把高容量转换到低容量的时候,强制转换
4、转换的时候可能存在内存溢出,或着精度问题
System.out.println((int) 23.7); // 23
System.out.println((int) -45.89f); //-45
转换时的问题
操作比较大的时候,注意溢出问题
// JDK7 新特性 数字之间可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money * years;
System.out.println(total); // -1474836480 计算时溢出
long total2 = money * years; // 默认是int,转换之前已经存在问题了
System.out.println(total2);// -1474836480
long total3 = money *((long)years); // 先把一个数转换成long
System.out.println(total3);// 2000000000
// L l
可以变化的量
// int a b c
// int a=1,b=2,c=3; //程序可读性
String name = "123";
char x = 'x';
double pi = 3.14;
注意:
变量作用域
public class Variable{
// 属性:变量
static int allClick = 0; // 类变量 static :从属于类
// 实例变量:从属于对象;如果不自行初始化,就是这个类型的默认值 0 0.0
// boolean 默认是false
// 除了基本类型,其余的默认值都是null
String str = "hello";
public void method(){
int i = 0; // 局部变量:必须声明和初始化值
}
// main方法
public static void main(String[] args) {
// 局部变量:必须声明和初始化值
int i = 10;
System.out.println(i);
Demo08 demo08 = new Demo08();
System.out.println(demo08.str);
System.out.println(allClick);
}
// 其他方法
public void add(){
}
}
变量的命名规范
常量:初始化后不能再改变值!不会变动的值
final 常量名 = 值;
public class Demo09 {
// 修饰符,不存在先后顺序
static final double PI = 3.14;
// final static double PI = 3.14;
public static void main(String[] args) {
System.out.println(PI);
}
}
算数运算符:+ ,-,*,/,%(取余/模),++,–
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);// 0.5 小心作用范围
}
}
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 默认是int类型
System.out.println((double)c+d); // double
}
}
public class Demo03 {
public static void main(String[] args) {
int a = 10;
int c = 21;
// 取余,模运算
System.out.println(c%a);// 21/10=2···1
}
}
// 重要!!!
public class Demo04 {
public static void main(String[] args) {
// ++ -- 自增,自减 一元运算符
int a = 3;
int b = a++; // 执行完这行代码后,先给b赋值,再自增
// a++ a=a+1;
System.out.println(a);// 4
// a++ a=a+1;
int c = ++a; // ++a a=a+1 执行完这段代码前,先给a自增,再给c赋值
System.out.println(a);// 5
System.out.println(b);// 3
System.out.println(c);// 5
// 幂运算 2^3 2*2*2=8 很多运算需要使用工具类来操作
double d=Math.pow(2,3);//8
System.out.println(d);
}
}
赋值运算符:=
关系运算符:>,<,>=,<=,==,!=,instanceof
public class Demo03 {
public static void main(String[] args) {
// 关系运算符返回的结果:正确,错误 boolean
int a = 10;
int b= 20;
System.out.println(a>b);//false
System.out.println(a<b);//true
System.out.println(a==b);// false
System.out.println(a!=b);// true
}
}
逻辑运算符:&&(与),||(或),!(非)
public class Demo05 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println(a&&b);// false 逻辑与运算,两个变量都为真,结果才为真
System.out.println(a||b); // true 逻辑或运算,两个都为假,结果才是假
System.out.println(!(a&&b));// true 如果是真,则为假
// 短路运算
int c = 5;
boolean d = (c<4)&&(c++<4);
System.out.println(d);// false
System.out.println(c);// 5
}
}
位运算符:&,|,^,~,>>,<<,>>>
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怎么算最快 2*2*2*2
* 左移 << *2
* 右移 >> /2
*/
System.out.println(2<<3); // 16
/**
* 0000 0000 0
* 0000 0001 1
* 0000 0010 2
* 0000 0011 3
* 0000 0100 4
* 0000 1000 8
* 0001 0000 16
*/
}
}
public class Demo08 {
public static void main(String[] args) {
// x ? y : z
// 如果x==true,则结果为y,否则为z
int score = 80;
String type = score < 60 ? "不及格":"及格";
}
}
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
a+=b;// a = a+b
a-=b;// a = a-b
System.out.println(a);//30
// 字符串连接符 + string
System.out.println(a+b);//30
// 注意!!!
System.out.println(""+a+b); // 1020
System.out.println(a+b+"");// 30
}
}
优先级
http://c.biancheng.net/view/794.html
一般利用公司域名倒置作为包名
// 导入这个包下所有的类
import com.kuang.base.*
在线API帮助文档https://docs.oracle.com/javase/8/docs/api/
Javadoc命令是用来生成自己API文档的
参数信息
# 命令行生成
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
IDEA 生成Javadoc文件
首先选择需要生成文档的代码
然后点击Tools—> Generate javaDoc
-encoding utf-8 -charset utf-8
点击ok,就生成javadoc文档
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);
}
// 凡是属于IO流的类,如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
}
}
public class Demo02 {
public static void main(String[] args) {
// 从解盘接收数据
Scanner scanner= new Scanner(System.in);
System.out.println("使用next方式接收:");
// 判断是否还有输入
if(scanner.hasNextLine()){
// 程序会等待用户输入
String str = scanner.nextLine();
System.out.println("输入的内容为:"+str);
}
scanner.close();
}
}
public class Demo03 {
public static void main(String[] args) {
// 从解盘接收数据
Scanner scanner= new Scanner(System.in);
System.out.println("请输入数据:");
String str = scanner.nextLine();
System.out.println("输入的内容为:"+str);
scanner.close();
}
}
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();
}
}
我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果:
public class Demo05 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 和
double sum = 0;
// 计算输入多少个数字
int m = 0;
// 通过循环判断是否还有输入,并在里面对每一次进行求和统计
while (scanner.hasNextDouble()){
double x = scanner.nextDouble();
System.out.println("你输入了第"+m+"个数据,然后当前结果sum="+sum);
m = m+1;// m++
sum = sum +x;
}
System.out.println(m+"个数的和为:"+sum);
System.out.println(m+"个数的平均值为:"+(sum/m));
scanner.close();
}
}
java的基本结构就是顺序结构,除非特别指明,否则就是按照顺序一句一句执行
public static void main(String[] args) {
System.out.println("hello1");
System.out.println("hello2");
System.out.println("hello3");
}
语句与语句之间,框与框之间是按从上到下的顺序进行的,他是由若干个依次执行的处理步骤组成的,是任何一个算法都离不开的一种基本算法结构
需要判断一个东西是否可行,然后我们才去执行,这样的一个过程在程序中用if语句来表示
语法:
if(布尔表达式){
// 如果布尔表达式为true将执行的语句
}
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(布尔表达式){
// 如果布尔表达式为true将执行的语句
}else{
// 如果布尔表达式为false将执行的语句
}
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(布尔表达式1){
// 如果布尔表达式1为true将执行的语句
}else if(布尔表达式2){
// 如果布尔表达式2为true将执行的语句
}else if(布尔表达式3){
// 如果布尔表达式3为true将执行的语句
}else{
// 如果以上布尔表达式都不为true将执行的语句
}
public class IfDemo03 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int score = scanner.nextInt();
if(score==60){
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{
System.out.println("不及格");
}
scanner.close();
}
}
if(布尔表达式1){
// 如果布尔表达1式为true将执行的语句
if(布尔表达式2){
// 如果布尔表达式2为true将执行的语句
}
}
判断一个变量与一系列值中的某个值是否相等,每个值称为一个分支
switch(exprssion){
case value:
// 语句
break;//可选
case value:
// 语句
break; // 可选
default:// 可选
// 语句
}
public class SwitchDemo01 {
public static void main(String[] args) {
char grade = 'c';
// case 穿透
// switch 匹配一个具体的值
switch (grade){
case 'a':
System.out.println("优秀");
break; // 可选
case 'b':
System.out.println("良好");
break;
case 'c':
System.out.println("及格");
break;
default:
System.out.println("不及格");
}
}
}
switch 语句中的变量类型可以是:
public class SwitchDemo02 {
public static void main(String[] args) {
String name = "狂神";
switch (name){
case "wer":
System.out.println("wer");
break;
case "狂神":
System.out.println("ks");
break;
default:
System.out.println("???");
}
}
}
public class SwitchDemo02 {
public static void main(String[] args) {
String name = "狂神";
// JDk7的新特性,表达式结果可以是字符串
// 字符的本质还是数字
switch (name){
case "wer":
System.out.println("wer");
break;
case "狂神":
System.out.println("ks");
break;
default:
System.out.println("???");
}
}
}
把class文件放入IDEA 就可以看到反编译后的文件
while(布尔表达式){
// 循环内容
}
只要布尔表达式为true,循环就会一直执行下去
大部分情况是会让循环停止下来的,需要一个表达式失效的方式来结束循环
少部分情况需要循环一直执行,比如服务器的请求响应监听等
尽量避免死循环,会影响程序性能或者造成程序卡死崩溃
public class WhileDemo01 {
public static void main(String[] args) {
// 输出1—100
int i=0;
while (i<100){
i++;
System.out.println(i);
}
}
}
public class WhileDemo02 {
public static void main(String[] args) {
// 死循环
while (true){
// 等待客户端链接
// 定时检查
// ···
}
}
}
思考:1+2+···+100=?
public class WhileDemo03 {
public static void main(String[] args) {
int i = 0;
int sum = 0;
while (i <= 100) {
sum = sum + i;
i++;
}
System.out.println(sum);//5050
}
}
至少会执行一次
do{
//代码语句
}while(布尔表达式);
while与do-while的区别:
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);//5050
}
}
for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构
for(初始化;布尔表达式;更新){
// 代码语句
}
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 循环结束");
// 初始化//条件判断 // 迭代 100.for(IDEA快捷键)
for(int i =1;i<=100;i++){
System.out.println(i);
}
System.out.println("for循环结束");
}
}
说明:
1、最先执行初始化步骤,可以声明一种类型,但可初始化一个或多个循环控制变了,也可以是空语句
for(;i<=100;i++){
System.out.println(i);
}
2、然后检测布尔表达式的值(为true循环体被执行,为false循环终止,开始执行循环体后面的语句)
3、执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)
4、再次检测布尔表达式,循环执行上面的过程
for(;;;){
// 死循环
}
练习
计算0-100之间的奇数和偶数的和
public class ForDemo02 {
public static void main(String[] args) {
// 计算0-100之间的奇数和偶数的和
int oddSum = 0;
int evenSum = 0;
for (int i = 0; i <= 100; i++) {
if(i%2!=0){ // 基数
oddSum+=i; // oddsum = oddsum + i
}else{ // 偶数
evenSum+=i;
}
}
System.out.println(oddSum);
System.out.println(evenSum);
}
}
使用while循环或者for循环输出1-1000之间能被5整除的数,并且每行输出3个
public class ForDemo03 {
public static void main(String[] args) {
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");
}
}
}
}
打印九九乘法表
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(声明语句:表达式){
//代码句子
}
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]);
}
// 遍历数组的元素
for (int x : numbers) {
System.out.println(x);
}
}
}
break 在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)
public class BreakDemo {
public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
System.out.println(i);
if(i==30){
break;
}
}
System.out.println("123");
}
}
continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
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.print(i);
}
}
}
public class LableDemo {
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.println(i+"");
}
}
}
练习
打印三角形
public class TestDemo01 {
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 方法是语句的集合,他们在一起执行一个功能
public class Demo01 {
// main 方法
public static void main(String[] args) {
int sum = add(1, 2);
System.out.println(sum);
}
// 加法
public static int add(int a, int b) {
return a + b;
}
}
public static void main(String[] args) {
//实际参数:实际调用传递给他的参数
int sum = add(1, 2);
System.out.println(sum);
}
// 加法
// 形式参数:用来定义作用的
public static int add(int a, int b) {
return a + b;
}
public class Demo02 {
public static void main(String[] args) {
int max =max(10,20);
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) 和 引用传递
java基本数据类型传递与引用传递区别详解
https://blog.csdn.net/javazejian/article/details/51192130
在一个类中,有相同的函数名称,但形参不同的函数
方法的重载规则:
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
有时候希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现
public class Demo03 {
public static void main(String[] args) {
// args.length 数组长度
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
JDK1.5 开始,Java支持传递同类型的可变参数给一个方法
public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
// 调用可变参数的方法
demo04.test(1,2,3,4,5);
}
// 本质是数组
public void test(int x,int... i){
System.out.println(i);
System.out.println(i[0]);
System.out.println(i[1]);
}
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("max ="+result);
}
}
自己调用自己
public class Demo05 {
public static void main(String[] args) {
Demo05 demo05 = new Demo05();
demo05.test();
}
public void test(){
test();
}
}
递归结构包含两个部分:
public class Demo06 {
// 1! 1
// 2! 2*1
// 3! 3*2*1
public static void main(String[] args) {
System.out.println(f(5));
}
// 2 2*f(1)
public static int f (int n ){
if(n==1){
return 1;
}else{
return n*f(n-1);
}
}
}
小计算可以用递归,大运算别用递归,会影响机器性能
数组是相同类型数据的有序集合
数组描述的是相同类型的若干个数据,按照一定的先后顺序排列组合而成
public class ArrayDemo01 {
// 变量的类型 变量的名字 = 变量的值
// 数组类型
public static void main(String[] args) {
int[] nums; // 声明一个数组 首选
int nums2[];
nums = new int[10];// 创建一个数组
// 给数组元素中赋值
nums[0]=1;
nums[1]=2;
nums[2]=3;
nums[3]=4;
nums[4]=5;
nums[5]=6;
System.out.println(nums[0]);
System.out.println(nums[6]);// 0
//计算所有元素大的和
int sum = 0;
// 获取数组的长度:arrays.length
for (int i = 0; i < nums.length; i++) {
sum =sum +nums[i];
}
System.out.println(sum);
}
}
java 内存分析:
静态初始化
动态初始化
public class ArrayDemo02 {
public static void main(String[] args) {
// 静态初始化:创建 + 赋值
int[] a = {1,2,3,4,5};
System.out.println(a[0]);//1
// 动态初始化: 包含默认初始化
int[] b = new int [10];
b[0] = 10;
System.out.println(b[0]);//10
System.out.println(b[1]);//0
}
}
数组的默认初始化
其长度是确定的,数组一旦被创建,大小就是不可以改变的
其元素必须是相同类型,不允许出现混合类型
数组中的元素可以是任何数据类型,包括基本类型和引用类型
数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。
数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中。
下标的合法区间是:【0,length-1】
如果越界就会报错:ArrayIndexOutOfBoundsException:数组下标越界异常
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
//打印全部的数组元素
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
// 计算所有元素的和
int sum = 0;
for (int i = 0; i < arrays.length; i++) {
sum += arrays[i];
}
System.out.println(sum);
// 查找最大元素
int max = arrays[0];
for (int i = 1; i < arrays.length; i++) {
if (arrays[i] > max) {
max = arrays[i];
}
}
System.out.println(max);
}
}
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
// jdk1.5 没有下标
for (int array : arrays) {
System.out.println(array);
}
}
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
printArray(arrays);
}
// 打印数组元素
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
}
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
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 class ArrayDemo05 {
public static void main(String[] args) {
/**
* 1,2 array[0]
* 2,3 array[1]
* 3,4 array[2]
* 4,5 array[3]
*/
int[][] array = {{1, 2}, {2, 3}, {3, 4}, {4, 5}};
printArray(array[0]);//1,2
System.out.println(array[0][0]);//1
System.out.println(array[0][1]);//2
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[i].length; j++) {
System.out.println(array[i][j]);
};
}
System.out.println(array.length);//4
System.out.println(array[0].length);//2
}
// 打印数组元素
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.println(arrays[i]);
}
}
}
public class ArrayDemo06 {
public static void main(String[] args) {
int[] a = {1,2,3,4,555,4324,21,234};
//打印数组元素
System.out.println(Arrays.toString(a));
// 排序 升序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
// 填充
Arrays.fill(a,0);
// 填充
Arrays.fill(a,2,4,0);
}
public 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.print(a[i]+"]");
}else{
System.out.print(a[i]+", ");
}
}
}
}
1、比较数组中,两个相邻的元素,如果第一个数比第二个数字大,我们就交换他们的位置
2、每一次比较,都会产生出一个最大,或者最小的数字
3、下一轮,可以少一次排序
4、依次循环,直到结束
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a ={1,3,2,4,6,5};
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));
}
// 冒泡排序
public static int[] sort(int[] array){
// 临时变量
int temp =0 ;
// 外层循环,判断需要走多少次
for (int i = 0; i < array.length; i++) {
// 内层循环,比较两个数,如果第一个比第二个大,则交换位置
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;
}
}
}
return array;
}
}
时间复杂度是O(n2)
如何优化?
package com.kuang.array;
import java.util.Arrays;
public class ArrayDemo07 {
public static void main(String[] args) {
int[] a ={1,3,2,4,6,5};
int[] sort = sort(a);
System.out.println(Arrays.toString(sort));
}
// 冒泡排序
public static int[] sort(int[] array){
// 临时变量
int temp =0 ;
// 外层循环,判断需要走多少次
for (int i = 0; i < array.length; i++) {
// 通过flag减少没有意义的比较
boolean flag = false;
// 内层循环,比较两个数,如果第一个比第二个大,则交换位置
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;
}
}
数据结构
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式:
package com.kuang.array;
import java.util.Arrays;
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;
// 输出原始素组
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
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;
// 遍历二维数组,将非0的值,存入稀疏数组
int cout = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if(array1[i][j]!=0){
cout++;
array2[cout][0]=i;
array2[cout][1]=j;
array2[cout][2]=array1[i][j];
}
}
}
// 输出
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"+array1[i][1]+
"\t"+array1[i][2]+
"\t");
}
// 还原
// 读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
// 给其中的元素还原他的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]]=array2[i][2];
}
// 打印
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt+"\t");
}
System.out.println();
}
}
}
面向过程思想
面向对象思想
面向对象:
package com.oop.demo01;
import java.io.IOException;
public class Demo01 {
// main 方法
public static void main(String[] args) {
}
/**
* 修饰符 返回值类型 方法(参数类型 参数名){
* //方法体
* return 返回值;
* }
* return 结束方法,返回一个结果 break :跳出switch
*/
public String sayHello(){
return "hello";
}
public int max(int a, int b ){
return a>b ? a : b;// 三元运算符
}
public void readFile (String file )throws IOException{
}
}
静态方法和非静态方法
public static void main(String[] args) {
// 非静态方法 实例化这个类 new
// 对象类型 对象名 = 对象值
Student student = new Student();
student.say();
// 静态方法
Student.say2();
}
// 和类一起加载的
public static void a(){
// b();
}
// 类实例化之后才会存在
public void b(){
}
// 学生类
public class Student {
// 静态方法
public static void say2(){
System.out.println("12222");
}
// 非静态方法
public void say(){
System.out.println("12333");
}
}
形参和实参
public static void main(String[] args) {
// 实际参数和形式参数的类型要对应
// 实际参数
new Demo03().add(1,2);
}
//形式参数
public 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);// 123
}
// 返回值为空
public static void change(Person person){
// person 是一个对象,指向的 Person person = new Person(); 这是一个具体的人,可以改变属性
person.name="123";
}
}
// 定义了一个person类,有一个属性:name
class Person{
String name; // null
}
类是一种抽象的数据类型,它是对某一类事物整体描述/定义,但是并不能代表某一个具体的事物
== 对象是抽象概念的具体实例 ==
使用new关键字创建对象
// 学生类
public class Student {
// 属性: 字段
String name;//null
int age; // 0
public void study(){
// this 指当前这个类
System.out.println(this.name+"在学习");
}
}
// 一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
// 类:是抽象的 需要实例化
// 类实例化后会返回一个自己的对象
// student对象就是一个student类的具体实例
Student xiaoming = new Student();
Student xh = new Student();
xiaoming.name="xiaoming";
xiaoming.age=3;
System.out.println(xiaoming.name);
System.out.println(xiaoming.age);
xh.name="xh";
xh.age=3;
System.out.println(xh.name);
System.out.println(xh.age);
}
}
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
IDEA:alt+insert 快捷键
构造器:
1、和类名相同
2、没有返回值
作用:
1、使用new关键字,本质是在调用构造器
2、用来初始化对象的值
注意点:
1、定义有参构造之后,如果想使用无参构造,显示的定义一个无参构造
// java --> class
public class Person {
String name;
// 一个类即使什么都不写,也会存在一个方法
// 显示的定义构造器
public Person(){
//实例化初始值
// 1、使用new关键字,本质是在调用构造器
// 2、用来初始化值
this.name = "123";
}
// 有参构造: 一旦定义了有参构造,无参构造就必须显示定义
public Person(String name){
this.name = name;
}
}
// 一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
// new实例化了一个对象
Person person = new Person();
System.out.println(person.name);//123
}
}
public class Pet {
public String name;
public int age;
public void shout(){
System.out.println("叫");
}
}
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name="旺财";
dog.age=3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat = new Pet();
}
}
堆:存放new的数组和对象(方法区属于堆)
栈:存放基本变量和引用变量(方法和引用)
1、类与对象
2、方法
3、对象的引用:
4、属性:字段field 成员变量
属性默认初始化:
修饰符 属性类型 属性名 = 属性值
5、对象的创建和使用
6、类:
(数据的隐藏—高内聚,低耦合)
高内聚: 就是类的内部数据操作细节自己完成,不允许外部干涉
低耦合: 仅暴露少量的方法给外部使用
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
属性私有,get/set
// 类 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){ // 不合法
this.age=3;
}else{
this.age = age;
}
}
}
// 一个项目应该只存在一个main方法
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.setName("123");
student.getName();
student.setAge(-1);//不合法
}
}
封装的意义:
1、提高程序的安全性,保护数据
2、隐藏代码的实现细节
3、统一接口
4、提高系统的可维护性
继承的本质是对某一批类的抽象,,从而实现对现实世界的更好的建模
extends 就是扩展的意思
// person 人 父类
public class Person {
}
// 学生 is 人 派生类,子类
public class Student extends Person{
}
// 派生类,子类
public class Teacher extends Person{
}
继承是类与类之间的一种关系。除此之外,类与类之间的关系还有依赖、组合、聚合等
继承关系的两个类,一个是子类(派生类),一个是父类(基类)。子类继承父类,使用关键字extends来表示。
// person 人 父类
public class Person {
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;
}
}
// 学生 is 人 派生类,子类
public class Student extends Person{
// 子类继承父类,就会拥有父类的全部方法
}
public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();
System.out.println(student.getMoney());
}
}
ctrl+h 可以查看到继承关系
在Java中,所有的类都默认直接或者间接继承object类
java中只有单继承,没有多继承
注意点:
1、super 调用父类的构造方法,必须在构造方法的第一个
2、super 必须只能出现在子类的方法或构造方法中
3、super 和 this 不能同时调用构造方法
Vs this::
1、代表的对象不同:this(本身调用者这个对象) super(代表父类对象的应用)
2、前提:this(没有继承也可以使用)super(只能在继承条件下才可以使用)
3、构造方法:this()本类的构造;super()父类的构造
// person 人 父类
public class Person /*extends object*/ {
protected String name = "111";
public Person() {
System.out.println("Person无参执行了");
}
// private 私有的东西无法被继承
public void print(){
System.out.println("Person");
}
}
// 学生 is 人 派生类,子类
public class Student extends Person {
// 子类继承父类,就会拥有父类的全部方法
private String name = "222";
public Student() {
// 隐藏代码 super():调用了父类的无参构造
super();// 调用父类的构造器,必须要在子类构造器的第一行
// this("hello"); // super 和 this 不能同时调用构造方法
System.out.println("Student无参执行了");
}
public Student(String name) {
this.name = name;
}
public void test(String name) {
System.out.println(name);//333
System.out.println(this.name);//222
System.out.println(super.name);//111
}
public void print() {
System.out.println("Student");
}
public void test1() {
print(); // Student
this.print();// Student
super.print();// Person
}
}
public class Application {
public static void main(String[] args) {
Student student = new Student();//Person无参执行了 Student无参执行了
// student.test("333");
// student.test1();
}
}
重写:需要有继承关系,子类重写父类的方法
1、方法名必须相同
2、参数列表必须相同
3、修饰符:范围可以扩大,但不能缩小。 public>protected>default>private
4、抛出的异常:范围,可以被缩小,但不能扩大:ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必须要一致,方法体不同!
为什么需要重写?
1、父类的功能子类不一定需要,或者不一定满足!
// 重写都是方法的重写,和属性无关
public class B {
// public static void test(){
// System.out.println("B-Test()");
// }
public void test(){
System.out.println("B-Test()");
}
}
// 继承
public class A extends B{
// public static void test(){
// System.out.println("A-Test()");
// }
// public void test(){
// System.out.println("A-Test()");
// }
// 重写
@Override
public void test() {
System.out.println("A-Test()");
}
}
public class Application {
// 静态方法和非静态的方法区别很大
// 静态方法 // 方法的调用,只和(左边)定义的数据有关
// 非静态方法 (重写) // 子类重写了父类的方法(重写只与非静态方法有关)
public static void main(String[] args) {
A a = new A();
a.test();// A
// 父类的引用指向了子类
B b =new A();
b.test();// B A(重写后)
}
}
动态编译:类型:可扩展性
即同一个方法可以根据发送对象的不同而采用多种不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)
多态注意事项:
1、多态是方法的多态,属性没有多态
2、父类和子类,有联系 (类型转换异常)ClassCastException
3、多态存在的条件:继承关系,方法需要重写,父类的引用指向子类对象 father f1 = new Son();
不能被重写的方法:
1、static 方法,属于类,不属于实例
2、final 常量
3、private 方法(私有)
public class Person {
public void run(){
System.out.println("run");
}
}
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
public class Application {
public static void main(String[] args) {
// 一个对象的实际类型是确定的
// new Student()
// 可以指向的引用类型就不确定了:父类的引用指向子类
// Student 能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
// 父类的引用指向子类:person 父类,可以指向子类 但是不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
// 对象能执行哪些方法主要看对象左边的类型,和右边关系不大
s2.run();// son 子类重写了父类的方法,执行子类的方法
s1.run();// son
// ((Student)s2).eat();
}
}
instanceof (类型转换) 引用类型,判断一个对象时什么类型
public class Person {
public void run(){
System.out.println("run");
}
}
public class Teacher extends Person{
}
public class Student2 extends Person{
}
public class Application {
public static void main(String[] args) {
// object> person> student
// object> person> teacher
// object> string
Object object = new Student2();
// System.out.println(x instanceof y);// 能不能编译通过
System.out.println(object instanceof Student2);// 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
Person person = new Student2();
System.out.println(person instanceof Student2);// 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);//编译报错
Student2 student = new Student2();
System.out.println(student instanceof Student2);// true
System.out.println(student instanceof Person);// true
System.out.println(student instanceof Object);// true
// System.out.println(student instanceof Teacher);// 编译报错
// System.out.println(student instanceof String);// 编译报错
}
}
多态
1、父类引用指向子类对象
2、把子类转换为父类,向上转型,自动转换
3、把父类转换为子类,向下转型,强制转换,可能会丢失自己的方法
4、方便方法的调用,减少重复的代码,简洁代码
public class Person {
public void run(){
System.out.println("run");
}
}
public class Student2 extends Person{
public void go(){
System.out.println("go");
}
}
public class Application {
public static void main(String[] args) {
// 类型之间的转换:父类 子类
// 高 低
Person obj = new Student2();
// student 将这个对象转换为Student类型,我们就可以使用Student类型的方法了
Student2 s = (Student2) obj;
s.go();
((Student2) obj).go();
// 子类转换为父类,可能会丢失自己的本来一些方法
Student2 student2 = new Student2();
Person person = student2;
}
}
// 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();
go();
System.out.println(Student.age);
System.out.println(s1.age);
System.out.println(s1.score);
}
}
public class Person {
// 2:赋初始值~
{
// 代码块(匿名代码块) 在构造器之前
System.out.println("匿名代码块");
}
// 1:只执行一次~
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.demo07;
//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Test {
public static void main(String[] args) {
System.out.println(random());
System.out.println(PI);
}
}
abstract 修饰符可以用雷修饰方法也可以修饰类,抽象方法和抽象类。
抽象类的特点:
1、不能new 这个抽象类,只能靠子类去实现它:约束
2、抽象类中可以写普通方法
3、抽象方法必须在抽象类中,抽象方法只有方法的声明,没有方法的是实现,它是用来让子类实现的
4、抽象类存在默认构造器
5、抽象类抽象出来,目的是为了提高开发效率
抽象的抽象:约束
// abstract抽象类 :类 extends (单继承)
public abstract class Action {
//约束 有人帮我们实现
// abstract , 抽象方法,只有方法名字,没有方法的实现
public abstract void doSomething();
public void hello(){
}
}
public class A extends Action{
// 抽象类的所有方法,继承他了的子类,都必须实现它的方法 ,除非A也是abstract
@Override
public void doSomething() {
}
}
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有!
接口:只有规范!自己无法写方法,专业的约束!约束和实现分离:面向接口编程
接口的本质是契约,声明接口的关键字是interface
// 抽象的思维
// interface 定义的关键字,接口都需要有实现类
public interface UserService {
// 常量 public static final
int AGE =99 ;
// 接口中的所有定义其实都是抽象的 public abstract
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
public interface TimeService {
void timer();
}
// 类 可以实现接口 implements 接口
// 实现了接口的类,就需要重写接口中的方法
// 多几次 利用接口实现多继承~
public class UserServiceImpl implements UserService,TimeService{
@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、必须要重写接口中的方法
内部类就是在一个类的内部在定义一个类。
public class Outer {
private int id = 10;
public void out() {
System.out.println("这时外部类的方法");
}
public class Inner {
public void in() {
System.out.println("这时内部类的方法");
}
// 内部类可以访问外部类的一些私有变量
// 获得外部类的私有属性 私有方法
public void getId() {
System.out.println(id);
}
}
}
public class Application {
public static void main(String[] args) {
Outer outer = new Outer();
// 通过外部类来实例化内部类
Outer.Inner inner =outer.new Inner();
inner.in();
inner.getId();
}
}
public class Outer {
private int id = 10;
public void out() {
System.out.println("这时外部类的方法");
}
public static class Inner {
public void in() {
System.out.println("这时内部类的方法");
}
}
}
public class Outer2 {
// 局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
}
public class Test {
public static void main(String[] args) {
// 没有名字初始化类,不用将实例保存在变量中
new Apple().eat();
// 匿名内部类
UserService userService= new UserService(){
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
异常指程序运行中出现的不期而至的各种情况,如:文件找不到,网络连接失败。异常发生在程序运行期间,它影响了正常的程序执行流程。
public class Demo01 {
public static void main(String[] args) {
System.out.println(11/0);
}
}
简单分类
error是由Java虚拟机生成并抛出的,大多数错误与代码编写者执行的操作无关。
Java虚拟机运行错误(Virtual MachineError),当jvm不再有继续执行操作所需的内存资源时,将出现 OutOfMemoryError(内存溢出)。这些异常发生时,Java虚拟机一般会选择线程终止。
还有发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError)、链接错误(LinkageError)。这些错误是不可查的,因为他们在应用程序的控制和处理能力之外,二千绝大多数是程序运行时不允许出现的状况。
在Exception分支中有一个重要的子类RuntimeException(运行时异常)
这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
Error和Exception的区别
error通常灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机一般会选择终止线程;
Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常
try 、catch、finally、throw、throws
public class Test {
public static void main(String[] args) {
int a =1;
int b =0;
// 假设要捕获多个异常:从小到大捕获
try{// try 监控区域
System.out.println(a/b);
}catch (ArithmeticException e){ // catch(想要捕获的异常类型) 捕获异常
System.out.println("程序出现异常,变量b不能为0");
}catch (Exception e){
System.out.println("Exception");
}catch (Throwable t){
System.out.println("Throwable");
}finally { // 处理善后工作
System.out.println("finally");
}
// finally 可以不要,假设IO,资源,关闭
try{// try 监控区域
new Test().a();
}catch (Throwable e){ // catch(想要捕获的异常类型) 捕获异常
System.out.println("程序出现异常,变量b不能为0");
}
}
public void a(){
b();
}
public void b(){
a();
}
}
IDEA 快捷键 ctrl +alt +t
public class Test2 {
public static void main(String[] args) {
int a =1;
int b =0;
try{
System.out.println(a/b);
}catch (Exception e){
e.printStackTrace();// 打印错误的栈信息
}
}
}
public class Test2 {
public static void main(String[] args) {
try{
new Test2().test(1,0);
}catch (ArithmeticException e){
e.printStackTrace();
}
}
// 假设这方法中,处理不了这个异常,方法上抛出异常
public void test(int a , int b) throws ArithmeticException{
if(b==0){// 主动抛出异常 throw throws
throw new ArithmeticException();// 主动抛出异常,一般在方法中使用
}
}
}
用户自定义异常类,只需要继承Exception类即可。
在程序中自定义异常类,可以有已下几个步骤:
1、创建自定义异常类
2、在方法中通过throw关键字抛出异常对象3、如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作
4、在出现异常方法的调用者中捕获并处理异常
// 自定义异常类
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 +
'}';
}
}
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);//MyException=>MyException{11}
}
}
}
1、处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
2、在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
3、对于不确定的代码,也可以加上try-catch,处理潜在的异常(IDEA Alt+enter)
4、尽量去处理异常,切记只是简单的调用printStackTrace()去打印输出
5、具体如何处理异常,要根据不同的业务需求和异常类型去决定
6、尽量添加finally语句块去释放占用的资源
【狂神说Java】Java零基础学习视频通俗易懂https://www.bilibili.com/video/BV12J41137hu