前言 碎碎念 java这门语言,我已经记不清开了多少课,敲了多少代码了。但是现在因为生活和学习上的需要,重新开课重新学习,颇有一种朝花夕拾的感觉。代码是以前敲过的代码,知识点是以前学过的知识点,现在只是重走西游路,在复习以前知识的同时找到自己。
关于笔记记录过程 按照本人复习过程来,力求逻辑上的完整性,重点放在逻辑上的连贯性,所以不会把理论和实践完全拆分开,在理论和实践的过程中推进。但是本质上还是为了期末的考试,所以会在最后加上一个做题和解析的模块。记录题目的同时方便自己查漏补缺。 本套笔记按照优先建立知识体系学习法,知识点的细节在学习和实战中慢慢完善。
JAVA的知识背景 java的诞生 JAVA由美国的SUN公司发明,诞生于1991年。 设计初衷是给机顶盒这类电子产品,这类产品的特点就是不同厂家生产的型号拥有不同的CPU不同的操作系统。 (为后续跨平台性埋下伏笔)因此要求JAVA产生的程序是中立的 (既跨平台) 可是命运总是爱跟人开玩笑,java发明之后这类产品直接褒姒,所以java失去了用武之地。 直到90年代中期互联网爆发,各式各样不同的电脑都连接到了互联网上(不同u不同系统) 此时急需一个跨平台语言,所以java堂堂崛起!
JAVA的主要应用范围 服务器端软件开发:各类网站系统和管理系统
移动端开发:安卓系统、鸿蒙
科学研究、云计算、大数据
JAVA的版本选择 目前企业中应用最广的还是java8.0,占据了最大的份额。
JVM、JRE、JDK JVM:Java Virtual Machine虚拟计算机 ,主要负责Java程序的运行 JAVA程序是在JAVA虚拟机上直接运行,而不是运行在操作系统上(有别于C++)Java的跨平台就是基于不同版本的JVM实现。 举例:我用mac系统写了一个JAVA程序,首先我MAC系统上需要有对应的MAC版JVM,所以程序在MAC上可以跑,然后我又把程序发给Linux系统,Linux系统上安装的Linux版JVM负责运行发送过去的程序
JRE :Java Runtime Environment, java运行时环境。 一张图解释
JRE包含了JVM,JRE是java运行环境,从字面上理解,java运行的时候JVM是必须的,因为Java的run就是run在JVM上。 加上核心的库类和文件,就组成了完整的运行环境。
JDK:Java Development kit ,Java 开发工具包。提供给java开发人员使用 再用一张图解释
JRE构成了运行JAVA的所有条件,JDK在此基础上加入了开发工具。
写出第一个JAVA程序。 JAVA的组织结构
关于java的组织结构和缩进 两个花括号一对,最外层下面的花括号对应上面的p,表示中间的部分是class类的类体 对于main方法来说,同理下面的花括号和上面的p对齐,两个花括号中间的部分是方法的方法体。
实际上java开发的步骤
从上图可以知道,虚拟机运行的程序都是.class文件,编写的程序是.java文件
简单的程序bug调试以及发散出的思维 关于bug: 1、bug说明程序有部分有错,也可以说明你离成功不远了,遇到bug是非常正常的事情 2、bug越多程序越复杂,程序越复杂bug越多 3、程序员的能力可以简单由调试bug的数量来判断,调试解决的bug越多,程序员的段位越高。 4、写不出bug的程序员是没有写代码的程序员,多写多错才会有所成长。
由bug发散的思维: 以下是刚才这个简单的bug我认为新手可能出现的错误以及原因 1、类名写错了 public class 后面的类名一定要和建的.java文件前面的名字相同,并且区分大小写 2、System的S打成小写,System.out.print 中的 System 是指 Java 的 java.lang.System 类。这个类是 Java 自带的,不需要额外导入,因为 java.lang 包是自动导入的。其中System是一个类,out是一个静态字段,print是一个方法(包括println)
标识符、关键字、变量本质、注释 标识符命名规则及使用规范 标识符命名规则
注:图中一个没有说到的细节就是可以以人民币符号¥开头,在我上课的PPT里面确实显示是可以的 我已经测试过了,确实是可以的。但是原理和图中说的有些出入 所以用一句话概括
开头字母钱标下划线,大小写敏感,区别关键字。
关于人民币符号¥ ¥符号也是作为”字母“被识别的,和中文和字母一样,因为Java用的是unicode字符集,¥和中文都满足,所以都可以作为”字母“被识别。而不是这个符号本身被识别。
标识符使用规范
主要是引入了驼峰原则,实际情况可能乱起名的人才是占了大多数
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Y24M10D4;public class Test002 { public static void main (String[] args) { int age = 1 ; int _age = 2 ; int $age = 3 ; int ¥age = 4 ; int age123 = 5 ; int 年龄 = 8 ; int _class = 10 ; } }
关键字 JAVA关键字是JAVA语言保留给内部使用的。所以关键字也叫保留字。 关键字都有特殊的含义,我们不能使用关键字作为标识符。 下面放一下java中的50个关键字,但是背是不可能背的,这辈子不可能背的。
变量 变量的本质 可操作的存储空间
用商场停车位来举例 商场有停车位,每个停车位有独一无二的编号,这个编号就是变量名 假设停车位编号A1,你停车之前A1就是一个空值,但是还是存在A1停车位 去停车的时候,你把车”小黑“停到一个A1,A1就有了自己的”值“ 小黑 所以A1 = 小黑 ,实际上是把小黑赋值给了A1。
测试代码
1 2 3 4 5 6 int monthlySalary = 3000 ;int annualSalary = monthlySalary*12 ;System.out.println(annualSalary); double bonus = 150.123 ;double sum = annualSalary+bonus;System.out.println(sum);
注释 重点 注释不会出现在字节码文件中(.class文件)。 java编译器编译的时候会跳过注释语句 同样的程序不管写多少注释写没写注释,编译之后的大小都是一样的。
分类
变量 八种基本数据类型
继续用上文是商场停车位来解释 高速休息站里的车位有不同的类型,SUV和越野车的车位大,卡车和客车的车位更大,卡车和客车的停车位可以停下小轿车和越野车,但是卡车和客车没办法停在小轿车和越野车的停车位里。 由此可知 :定义数据类型就是定义停车位的大小和类型 JAVA是一种 强类型语言 ,每个变量都必须声明数据类型
整型数据类型
派生知识点:
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package Y24M10D4;public class Test003 { public static void main (String[] args) { byte age = 18 ; short salary = 25000 ; int salary2 = 50000 ; int pekingPopulation = 30000000 ; int t1 = 65 ; int t2 = 065 ; int t3 = 0x65 ; int t4 = 0b01000001 ; System.out.println(t1+"\n" +t2+"\n" +t3+"\n" +t4); } }
浮点型数据类型
可以看到浮点数的表数范围非常大,这是因为浮点数是不精确 的
需要注意: 指定范围内的整数是有限的,比如0-10,但是0-10之间的小数是无限的。 因此,有限的空间存储无限的数据,必然存在误差,所以浮点数不能精确表示。 如果需要进行不产生舍入误差的精确计算,就需要引入BigDecimal类。后续再说。
实操代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 double d1 = 3.14 ; float f1 = 3.14F ; double d2 = 314E-2 ; System.out.println(d1+"\n" +f1+"\n" +d2); float f3 = 0.1F ; double d3 = 0.1 ; System.out.println(f3 == d3);
Char字符集 说到char字符,首先要注意String类型String是字符串不是基本数据类型! 是一个类!包含在Java.lang包里面,自动引入 本质上是一个字符的数组
ASCII字符集 ASCII字符集由美国国家标准协会指定,由一个字节的后7位来表示一个字符。(所以一共有2^7 128字符) 剩下的最高位一般为0 例 字母A在计算机中就是01000001 也就是65 ASCII字符非常简单,就是一个简单的查表的过程(如下图)
字符集的发展过程
ISO GB BIG5,都是不同地区自己制定的标准,由于不互通,经常造成乱码问题 所以有了Unicode字符集,每个字符都基于了全球独一无二的编码
Unicode原理 unicode采用了字符集和编码分开的策略。
unicode统一采用了两个字节表示一个字符,包括英文字母 但是因为英文占据了互联网信息的绝大部分,所以在传输过程中会造成极大的浪费 所以现在主流的UTF-8
UTF-8 用1-6个字节来编码表示Unicode字符,西欧字符仍然是一个字节,汉字是三个字节
转义字符 对照表格
布尔类型 布尔类型由两个常量,一个true 一个false组成 在内存中占1或4个字节。和C的区别 :不可以使用0或非0的整数来代替t或者f 常用来坐判断逻辑的条件。
练习代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package Y24M10D4;public class Test004 { public static void main (String[] args) { char c1 = 'A' ; char c2 = '薯' ; System.out.print(c1); System.out.print(c2); char c3 = '\n' ; char c4 = '片' ; System.out.print(c2); System.out.println(c3); System.out.println(c4); String str = "\n薯片" ; String str2 = "\n\n\"床前\"\t明\'月光\'" ; System.out.println(str2); boolean flag = true ; if (flag){ System.out.println("我在写代码" ); } } }
基本运算符 运算符分类
算术运算符
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 System.out.println("==========算术运算符=========" ); int a = 3 ;int b = 4 ;int c = a + b * 4 ;int c1 = (a + b) * 4 ;System.out.println("c=" + c); System.out.println("c1=" + c1); int d1 = 15 /4 ;int d2 = 15 %4 ;System.out.println("d1=" +d1 +"\n" +"d2=" +d2); a = 10 ; b = a ++; System.out.println("b=" +b +"\n" +"a=" +a); a = 10 ; b = ++a; System.out.println("b=" +b +"\n" +"a=" +a);
扩展运算符
运算符和表达式完全等效 没有过多的说明,用的情况也少 代码示例
1 2 3 4 5 6 System.out.println("==========拓展运算符=========" ); a = 20 ; b = 30 ; a += b; System.out.println("a=" +a + "\n" +"b=" +b);
关系运算符
关系运算符的计算结果为布尔值 代码示例
1 2 3 4 5 System.out.println("==========关系运算符=========" ); a = 20 ; b = 30 ; boolean result = a<b; System.out.println(result);
逻辑运算符 这一块基本上用图片来说明
短路与、或可以节省计算量,提前返回ture或false
关于异或 个人理解就是简单的 “不同” A和B不同 结果就是true A和B相同 结果就是false 因为不是 “不同” 注意异或的符号是^,幂运算的符号,但是表示的不是幂运算 java中幂运算(科学计数法)要用E来表示 比如 xEy 就是x乘10的y次方 示例代码
1 2 3 4 5 6 7 8 9 10 11 System.out.println("==========逻辑运算符=========" ); boolean b1 = true & false ;boolean b2 = true | false ;boolean b3 = !b2;boolean b4 = true ^true ;System.out.println("b1=" + b1 +"\n" +"b2=" + b2 +"\n" +"b3=" + b3 +"\n" +"b4=" + b4 ); int w = 3 /0 ;boolean b5 = 3 <4 || (4 <4 /0 ); System.out.println(b5);
位运算符
例如“3”的二进制:00000000 00000000 00000000 00000011 取反就是: 11111111 11111111 11111111 11111100 示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 System.out.println("==========位运算符=========" ); int m = 3 ; int n = 7 ; int p1 = m&n; System.out.println("p1=" +p1); int p2 = m | n ; int p3 = m^n ; int p4 = ~m; System.out.println("p2=" +p2); System.out.println("p3=" +p3); System.out.println("p4=" +p4); int m2 = 3 <<3 ; int m3 = 12 >>2 ; System.out.println("m2=" +m2); System.out.println("m3=" +m3);
字符串连接符 字符串连接符指的是+在连接字符时自动变为字符串连接符,会失去+原本的加的功能 代码示例:
1 2 3 4 5 System.out.println("==========字符串连接符=========" ); int r1 = 3 ;int r2 = 4 ;System.out.println(r1 + r2); System.out.println("result is" +r1+r2);
条件运算符 条件运算符可以很方便的替代if_else语句中的某些特殊情况
示例代码
1 2 3 4 System.out.println("==========条件运算符========="); int y1 = 30; int y2 = 40; int minY = y1<y2?y1:y2;//返回y1y2中比较小的值
此致,java中所有的基本运算符都已经学完了
数据类型自动和强制转换 自动类型转换
自动类型转换指容量小的数据类型可以自动转换为容量大的数据类型
注意 :这里的容量大小,指的不是字节数 ,而是表数范围 例如八个字节的long可以自动转换为四个字节的float
图中的实线表示的是无数据丢失的自动类型转换,虚线表示的是可能会有数据丢失的自动类型转换。
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package Y24M10D4;public class Test006 { public static void main (String[] args) { long a1 = 3456 ; float a2 = a1; System.out.println("a1=" + a1 + "\n" + "a2=" + a2); byte b1 = 121 ; long c1 = 1234 ; int c2 = 123 ; long c3 = c1 + c2; double d1 = 3.14 ; int d2 = 3 ; double d3 = d1+d2; double m1 = 3.98 ; int m2 = (int )m1; System.out.println("m2=" + m2 ); char m3 = 'C' ; int m4 = m3 + 2 ; char m5 = (char )m4; System.out.println("m5=" + m5); int n1 = 300 ; byte n2 = (byte )n1; System.out.println("n2=" +n2); int salary = 1000000000 ; int years = 30 ; long total2 = 1L *salary*years; System.out.println(total2); } }
通过键盘输入 流程控制语句 流程控制语句有两种结构 1、选择结构 2、循环结构 学会了程序控制语句,我们的一只脚就迈进了程序员的大门。
编程的本质 编程的本质就是用代码表达现实世界的逻辑。 而现实世界中的任何逻辑,最终都可以拆分成选择结构和循环结构。
选择结构代表 如果…则… 这样的逻辑 例:如果看到红灯 则立即停车 循环结构就是选择结构的基础上加上重复执行。 任何的编程 本质上都是由“变量、选择语句、循环语句”组成
if语句
语法结构
流程图
if else语句
多分支结构
示例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package Y24M10D4;public class Test010 { public static void main (String[] args) { System.out.println(Math.random()); int r = (int )(Math.random() * 10 ); System.out.println(r); if (r<5 ){ System.out.println("数比较小" ); } if (r<5 ){ System.out.println("number is small" ); }else { System.out.println("number is big" ); } int age = (int )(Math.random()*100 ); if (age<15 ){ System.out.println("childhood" ); } else if (age<25 ) { System.out.println("teenage" ); } else if (age<45 ) { System.out.println("adult" ); }else if (age<65 ){ System.out.println("old man" ); }else if (age<85 ){ System.out.println("get rest" ); } else { System.out.println("die" ); } } }
特殊练习,数字和字母的转换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package Y24M10D4;public class Test011 { public static void main (String[] args) { int num = (int )(Math.random()*26 ); char alpha = 'a' ; alpha = (char )(alpha + num); if (alpha == 'a' || alpha == 'e' ||alpha == 'i' ||alpha == 'o' ||alpha == 'u' ){ System.out.println("元音" ); }else { System.out.println("辅音" ); } } }
Switch语句 switch语句特别适合做多值判断代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 package Y24M10D9;public class Test001 { public static void main (String[] args) { int grade = (int )(Math.random()*4 ); if (grade == 1 ){ System.out.println("grade 1" ); } else if (grade ==2 ) { System.out.println("grade 2" ); } else if (grade == 3 ) { System.out.println("grade 3" ); }else { System.out.println("grade 4" ); } switch (grade){ case 1 : System.out.println("grade 1" ); break ; case 2 : System.out.println("grade 2" ); break ; case 3 : System.out.println("grade 3" ); break ; case 4 : System.out.println("grade 4" ); break ; } int month = (int )(Math.random()*12 ); if (month ==1 || month ==2 || month == 3 ){ System.out.println("spring" ); } else if (month ==4 || month ==5 || month == 6 ) { System.out.println("summer" ); } else if (month ==7 || month ==8 || month == 9 ) { System.out.println("autumn" ); }else { System.out.println("winter" ); } switch (month){ case 1 : case 2 : case 3 : System.out.println("spring" ); break ; case 4 : case 5 : case 6 : System.out.println("summer" ); break ; case 7 : case 8 : case 9 : System.out.println("autumn" ); break ; default : System.out.println("winter" ); break ; } } }
switch的表达式
switch语句练习
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 package Y24M10D9;public class Test002 { public static void main (String[] args) { int num = (int )(Math.random()*10 ); String Character = "" ; switch (num){ case 0 : Character = "zero" ; break ; case 1 : Character = "one" ; break ; case 2 : Character = "two" ; break ; case 3 : Character = "three" ; break ; case 4 : Character = "four" ; break ; case 5 : Character = "five" ; break ; case 6 : Character = "six" ; break ; case 7 : Character = "seven" ; break ; case 8 : Character = "eight" ; break ; case 9 : Character = "nine" ; break ; } System.out.println(Character); int score = (int )(Math.random()*10000 ); System.out.println("用户积分:" + score); switch (score/1000 ){ case 9 : case 8 : case 7 : System.out.println("apple" ); break ; case 6 : case 5 : System.out.println("banana" ); break ; case 4 : case 3 : System.out.println("milk" ); break ; default : System.out.println("none" ); break ; } } }
循环结构
一切的事物,核心都是循环,操作系统的核心是一个接一个的循环 屏幕显示是一个循环,键盘监听、鼠标监听,都是循环 大到宇宙的运行,也是循环;微观粒子运行,还是循环。 人生,也是循环。 循环结构分为两个
while循环和for循环
whlie的语法结构
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package Y24M10D9;public class Test003 { public static void main (String[] args) { int i = 1 ; while (i<101 ){ System.out.println("i=" +i); i++; } i =0 ; int sum = 0 ; while (i<101 ){ sum += i ; i++; } System.out.println("和:" +sum); } }
for循环
只不过for循环的语法做了一些调整
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 for (int i1 = 0 ;i1<10 ;i1++){ System.out.println("i1=" +i1); } int sum02 = 0 ; for (int m = 8 ;m<10 ;m++){ sum02 += m; } System.out.println("sum02=" + sum02); } }
嵌套循环 嵌套循环就是大循环里面套着小循环
这样可以解决更加复杂的问题
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 package Y24M10D9;public class Test004 { public static void main (String[] args) { for (int l = 0 ; l <= 10 ; l++) { for (int h = 0 ; h < 10 ; h++) { System.out.print(h + "\t" ); } System.out.println(); } for (int i = 0 ; i < 5 ; i++) { for (int j = 0 ; j < 5 ; j++) { if (j % 2 == 0 ) { System.out.print("奇\t" ); } else { System.out.print("偶\t" ); } } System.out.println(); } for (int m = 0 ; m<6 ; m++){ for (int n = 0 ; n<6 ;n++){ System.out.print("*\t" ); } System.out.println(); } for (int m = 0 ; m<6 ; m++){ for (int n = 0 ; n<m;n++){ System.out.print("*\t" ); } System.out.println(); } System.out.println("========" ); for (int m = 0 ;m<6 ;m++){ for (int n=5 ;n>5 -m;n--){ System.out.print("*\t" ); } System.out.println(); } System.out.println("========" ); for (int m = 0 ;m<6 ;m++){ for (int n=0 ;n<5 -m;n++){ System.out.print("*\t" ); } System.out.println(); } int num = 4 ; for (int i=0 ;i<5 ;i++){ for (int j=0 ;j<10 ;j++){ if (j>=num-i && j<=num+i){ System.out.print("*\t" ); }else { System.out.print("\t" ); } } System.out.println(); } } }
break和continue语句
这段多说无益,直接上代码,通过代码来了解
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 package Y24M10D9;public class Test005 { public static void main (String[] args) { int count = 0 ; while (true ){ int m = (int )(Math.random()*100 ); count +=1 ; System.out.println(m); if (m == 88 ){ break ; } } System.out.println("count:" +count); int a = 0 ; for (int i = 100 ;i<151 ;i++) { if (i % 3 == 0 ) { continue ; }else { System.out.print(i+"\t" ); a++; } if (a % 5 == 0 ) { System.out.println(); } } } } package Y24M10D9;public class Test006 { public static void main (String[] args) { int count = 0 ; for (;;){ int num = (int )(Math.random()*5 ); String animal = "" ; switch (num){ case 0 : animal = "tiger" ; break ; case 1 : animal = "eagel" ; break ; case 2 : animal = "pussy" ; break ; case 3 : animal = "doggy" ; break ; case 4 : animal = "bird" ; break ; default : animal="unknow animal" ; break ; } if (animal =="tiger" ){ System.out.println(animal); break ; } else if (animal == "eagel" ) { System.out.println(animal); continue ; }else { count++; System.out.println(animal); System.out.println(count); } } } }
控制语句综合练习 练习代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package Y24M10D9;import java.util.Scanner;public class Test007 { public static void main (String[] args) { char character = 'a' ; for (int i = 0 ;i<26 ;i++){ System.out.println(character); character++; } for (int m=1 ; m<10 ;m++){ for (int n = 1 ;n<=m;n++){ int k = m*n; System.out.print(m+"*" +n+"=" +k+"\t" ); } System.out.println(); } Scanner scanner = new Scanner (System.in); System.out.println("annual salary calculator" ); while (true ){ System.out.println("enter your salary:" ); int monthSalary = scanner.nextInt(); System.out.println("Enter the number of times you are paid in a year:" ); int months = scanner.nextInt(); int yearSalary = monthSalary * months; System.out.println("your annual salary:" + yearSalary ); if (yearSalary>=200000 ){ System.out.println("king!" ); }else if (yearSalary>=100000 ){ System.out.println("victory" ); } System.out.println("enter [88] to exit,enter [66] to continue" ); int commandNum = scanner.nextInt(); if (88 ==commandNum){ System.out.println("exit" ); break ; }else if (66 == commandNum){ System.out.println("please reenter" ); continue ; } } } }
方法的定义_内存结构 JAVA中的方法与函数的关系 在 Java 中只使用“方法”(method)这个术语,而没有“函数”(function)的概念。Java 的方法(method)与其他编程语言中的函数(function)非常相似,它们都执行特定的任务并可以返回一个值。但是由于 Java 是面向对象的语言,所有方法必须属于一个类,因此使用“方法”这个词来强调它们是类的成员。
方法的定义和调用
方法的声明格式 1 2 3 *多个修饰符 返回值类型 方法名(形势参数列表){ 多个java语句; }
这里修饰符就是public static,对于现在来说不是很重要,只要记住就行 具体的情况之后再解释
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 package Y24M10D4;public class Test007 { public static void main (String[] args) { int a1 = add(100 ,200 ); int a2 = add(200 ,300 ); int a3 = add(300 ,500 ); int num1 = 10 ; int num2 = 20 ; int sum = add(num1,num2); System.out.println("两个数的和" + sum); printInfo(); printInfo(); printInfo(); } public static int add (int n1,int n2) { int sum = n1 + n2; return sum; } public static void printInfo () { System.out.println("玲珑山车神" ); } }
方法的修饰符 可见性修饰符:
public—在所有类中可见,在其他包中可以用import导入。缺省—就是没有修饰符,在同一个包中的类中可见,在其他包中不能用import导入。
修饰符:
final—终态类,表示该类不能被继承abstract—抽象类,不能新建对象
方法调用过程 首先我们有一个叫栈的空间
最初始的情况他是空的 然后看上面的示例代码,当我们执行到main方法(main方法是程序的入口)的时候 栈空间内部出现一个关于main方法的栈帧。(stack frame)
每一个栈帧里面都包含main方法相关的信息 生成一个局部变量表,把上文main方法中的局部变量都放到表内
当程序执行到int sum的时候,这里就需要调用一个新的add方法 开辟一个新的栈帧
然后生成新的局部变量表
调用函数的时候,把需要的局部变量的值传递进来。
当调用printInfo()的时候,也同样会生成printInfo()的栈帧。
打印完了之后直接车从栈里面出去 出栈 同时main方法执行完毕,main方法也出栈 然后栈就空了,然后整个程序结束执行。
方法的重载 overload 方法的重载,指的是一个类中可以定义多个方法名相同,但参数不同的方法。调用时会根据不同的参数自动匹配对应的方法。
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 package Y24M10D11;public class Test004 { public static void main (String[] args) { System.out.println(add(100.25 ,100 )); System.out.println(add(100 ,100 )); System.out.println(add(100 ,100 ,100 )); System.out.println(add(100 ,100.25 )); } public static int add (int n1 , int n2) { int sum = n1 + n2; return sum; } public static double add (double n1,int n2) { double sum = n1+n2; return sum; } public static int add (int n1 , int n2, int n3) { int sum = n1 + n2 + n3; return sum; } public static double add (int n1 , double n2) { double sum = n1+n2; return sum; } }
面向对象 类的基本元素
属性
初始化 初始化就是赋一个默认值给这个成员变量,详见下面的成员变量的默认值
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package Y24M10D13;public class Student { int id; String name; int score; int age; public void study () { System.out.println(name + "is Studying" ); } }
成员变量的默认值
规则:对于数字 可以是0的都赋值为0,对于字符 赋值\u0000 本质也是0 对于布尔默认是 false 占一个字节 实际上也是0 引用类型: 从现在面向对象开始讲解的新的类型 自定义的类型 都是引用类型。 比如上文定义的student 就是一个引用类型
类和对象的关系 什么是对象?万物皆对象,在JAVA中,对象就是一类数据的实例化,他们有着一种或几种的相同特征。
个人理解 :用之前使用的过的写过的代码举例就是,比如说定义了 一个int类型的数据a1 那么就是存在一个a1,这个a1就是对象,属于的类是int类 比如说上文建立了一个student 的类之后,我再输入下面的语句
1 2 3 4 public static void main (String[] args) { Student stu1 = new Student (); }
就是创建了一个新的对象 这个对象的名字叫stu1 属于student的类 同时他也是所谓的引用类型变量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 package Y24M10D13; int id; String sname; int age; Computer computer; void study () { System.out.println("我正在使用:" + computer.brand+"学习" ); } public static void main (String[] args) { Computer c1 = new Computer (); c1.brand = "lenovo" ; c1.price = 6000 ; Computer c2 = new Computer (); c2.brand = "Republic of Gamers" ; c2.price = 9000 ; Computer c3 = new Computer (); c3.brand = "alienware" ; c3.price = 10000 ; BaizhanStudent stu01 = new BaizhanStudent (); stu01.id = 1001 ; stu01.sname = "疯狂小扬哥" ; stu01.age = 18 ; stu01.computer = c1; stu01.study(); } } package Y24M10D13;public class Computer { String brand; int price; }
以上是这段的示例代码,以下来讲述底层内存中的变化 首先内存中有栈和堆
当我们启动哦那这个类进行运算的时候。 内存中首先会做类的加载动作。 双引号中的内容,会被优先做处理,在堆中生成。
然后开始执行main方法,生成栈帧和局部变量表,其中c1 c2 stu1这些都是引用类型(四字节)
然后创建一个computer对象,并给他的两个属性赋默认值。
然后这个对象会有一个地址 例0x11(0x代表16进制)这个数我随便写的,无特殊含义 也可以用十进制写个2345 反正就是一个标记,告诉我们这个对象的地址是多少。 然后这里对象就建立完成了,建立完成了之后会把这个值个给c1,也就是那个0x11
同时这也就意味着,c1这个变量指向了这个对象。 这个时候就可以通过c1找到这个对象。 这时候就可以通过C1找到这个对象。 因为他引用了这个对象的地址。 然后再看下一步c1.brand = 联想 假设这里给联想一个虚拟的值0x88 然后堆中相当于c1.brand = 0x88
也就是c1.brand引用了0x88,然后c1.price 重新赋值=6000 因为c1.price是基本数据类型,基本数据类型是直接赋值给他,引用数据类型才是给地址。
c2h和stu1的定义过程也是同理,这里就不赘述了,直接上结果
注意 堆内存中的数据不会清除。因为不确定之后是否还会要被调用
构造方法constructor
构造器的定义
构造器 的四个要点
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Y24M10D17;public class Point { double x; double y; public Point (double _x,double _y) { x = _x; y = _y; } public static void main (String[] args) { Point p1 = new Point (3.0 ,4 ); System.out.println(p1.x); } }
创建对象的步骤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Y24M10D17;public class User { int id; String uname; String pwd; User(){ } public User (int _id) { id = _id; } public User (int _id,String _uname, String _pwd) { id = _id; uname = _uname; pwd = _pwd; } public static void main (String[] args) { User u1 = new User (); User u2 = new User (1001 ); User u3 = new User (1001 ,"13" ,123456 ); } }
构造方法的重载
内存 栈 和 堆 java虚拟机完整的内存模型
简化模型
栈的特点
1、栈描述的是方法执行的内部模型。每个方法被调用都会船舰一个栈帧(存储局部变量、操作数、方法出口等) 2、栈的存储特性是“线进后出,后进先出” 3、栈是由系统自动分配,速度快!栈是一个联系的内存空间! 其他特性: 4、JVM为每个线程出啊昂建一个栈,用于存放改线程执行方法的信息(实际参数、局部变量等) 5、栈属于线程私有,不能实现线程之间的共享
如同上面的方法,假设main方法中调用了另一个A方法,那么在mian方法上面加入那个调用的A方法的栈帧A 然后假设A方法又调用了一个B方法,那么在A方法的上面再加入一个B方法的栈帧B 然后最后加入的栈帧B方法执行完了之后最先离开栈帧,然后A方法执行完了之后再离开栈帧,最后是main方法 也就是说越早调用的越晚离开。
堆的特点
1、堆用于存储创建好的对象和数组(数组也是对象) 2、堆是一个不连续的内存空间,分配灵活,速度慢! 3、JVM只有一个堆,被所有线程共享。
方法区
1、方法区是JAVA虚拟机规范,可以有不同的实现。(比如JDK8是“元数据空间”和堆结合起来 2、方法区实际上也是堆,只是用于存储类、常量相关的信息! 3、用来存放程序中永远是不变或者唯一的内容。(类信息【class对象,放射机制中会重点讲授】、静态变量、字符串常量等) 4、JVM只有一个方法区,被所有线程共享!
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Y24M10D17;public class Person { String name; int age; public void show () { System.out.println("姓名:" + name + "\t年龄:" +age); } Person(String _name,int _age){ name = _name; age = _age; } Person(){ } public static void main (String[] args) { Person p1 = new Person (); p1.age = 24 ; p1.name = "张三" ; p1.show(); Person p2 = new Person ("李四" ,30 ); p2.show(); } }
当执行这段代码的时候 首先 在堆内存中的方法区生成这个person 类 然后固定的字符串也一起存储在方法区
然后在栈中生成main方法的栈帧 然后执行person p1的时候,现在栈帧中生成p1,但是此时p1的值为null, 然后执行后半句的时候
执行后半句的时候,调用构造器,在堆中创建person的对象,然后把地址返回给p1(假设地址为0x23)
此时栈帧中储存的p1 也就有了值(地址)
然后执行接下来的语句,把堆内存中的p1对象(0x23对象)中的age赋值24,在吧name的值改为张三的地址
然后再往下调用show方法打印
执行完了show方法之后直接出栈 P2的过程也是同理
this 的本质 this的本质就是”当前对象的地址!” 普通方法中,this总是指向调用该方法的对象 构造方法中,this总是只想正要初始化的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package Y24M10D19;public class User { int id; String name; String pwd; public User () { } public User (int id,String name) { System.out.println("正在要初始化的对象:" + this ); this .id = id; this .name =name; } public User (int id,String name,String pwd) { this (id, name); this .pwd = pwd; System.out.println("正在要初始化的对象:" + this ); } public void login () { System.out.println("要登陆:" +this .name+",密码:" +this .pwd); } public static void main (String[] args) { User u1 = new User (101 ,"薯片" ); u1.login(); User u2 = new User (102 ,"薯条" ,"123" ); u2.login(); } }
static的本质 static关键字核心用法: 用static声明的变量为静态成员变量,也成为类变量 1、重属于类,只有一份,在类被载入时被显式初始化。 2、一般用“类名.属性/方法”来调用 3、在static方法中不可直接访问非static的成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package Y24M10D19;public class TestStatic { int id; static String company = "薯片责任有限公司" ; static int companyId = 0 ; static { System.out.println("类被初始化的调用" ); companyId = 111222 ; } static void printCompany () { System.out.println("公司信息" +company); } void login () { System.out.println("登录" ); } public static void main (String[] args) { TestStatic.printCompany(); TestStatic t1 = new TestStatic (); t1.login(); TestStatic t2 = new TestStatic (); t2.login(); } }
继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package Y24M12D31;class Person { String name = "A" ; int height; public void rest () { System.out.println("rest" ); } } class Student extends Person { String major; public void study () { System.out.println(this .name+" is study" ); } public Student (String name,int height,String major) { this .name = name; this .height =height; this .major = major; } } public class Test001 { public static void main (String[] args) { Student s1 = new Student ("jack" ,180 ,"math" ); s1.study(); s1.rest(); } }
重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package Y24M12D31;class Vehicle { public void run () { System.out.println("run" ); } public void stop () { System.out.println("stop" ); } } class Horse extends Vehicle { @Override public void run () { System.out.println("马在跑" ); } @Override public void stop () { System.out.println("马停了" ); } } class aircraft extends Vehicle { @Override public void run () { System.out.println("飞机在飞" ); } @Override public void stop () { System.out.println("降落了" ); } } public class Test002 { public static void main (String[] args) { Horse h1 = new Horse (); h1.run(); h1.stop(); aircraft a1 = new aircraft (); a1.run(); a1.stop(); } }
final关键字
类似c++中的const
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 package Y24M12D31;class Base { public void func () { System.out.println("Base func()" ); } public final void func2 () { System.out.println( "base func02()" ); } } class Son extends Base { @Override public void func () { System.out.println("sons base func" ); } } final class Base02 { } public class Test003 { public static void main (String[] args) { final int maxSpeed = 120 ; } }
封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package Y24M12D31.a;public class BYD extends Car { void test () { super .addOil(); super .autoLighten(); super .run(); } } package Y24M12D31.a;public class Car { int id; String brand; private void check () { System.out.println("Car_check" ); } void addOil () { System.out.println("car.addoil" ); } protected void autoLighten () { System.out.println("car.autoLighten" ); } public void run () { System.out.println( "car.run" ); } } package Y24M12D31.b;import Y24M12D31.a.Car;public class Testla extends Car { void test () { super .autoLighten(); super .run(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package Y24M12D31;public class User { private int id; private String name; private String pwd; private boolean admin; public boolean isAdmin () { return admin; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getPwd () { return pwd; } public void setPwd (String pwd) { this .pwd = pwd; } public int getId () { return id; } public void setId (int id) { this .id = id; } public void login () { System.out.println("Userlogin" ); } } package Y24M12D31;public class Test004 { public static void main (String[] args) { User u1 = new User (); u1.setId(100 ); System.out.println(u1.getId()); } }
多态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 package Y24M12D30;public class Test001 { public static void main (String[] args) { Dog d1 = new Dog (); AnimalCry(d1); } static void AnimalCry (Animal a1) { a1.shout(); } } package Y24M12D30;import Y24M12D30.Animal;public class Animal { public void shout () { System.out.println("动物叫" ); } } class Dog extends Animal { @Override public void shout () { System.out.println("汪汪汪" ); } } class Cat extends Animal { @Override public void shout () { System.out.println("喵喵" ); } }
抽象方法和抽象类
在类中的方法前面加上abstract变成抽象方法,只要有了一个抽象方法这个类必须定义成抽象类 类定义的前面也要加上abstract,这个类中还可以有其他不抽象的方法,然后在他的子类中 必须要实现他的抽象方法,否则编译不通过,或者也会当成抽象类。 抽象类无法实例化对象,也就是说new不出来新的这个类的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package Y24M12D30;import Y24M12D30.Animal;public abstract class Animal { public abstract void shout () ; public void sleep () { System.out.println("sleep" ); } } class Dog extends Animal { @Override public void shout () { System.out.println("汪汪汪" ); } } class Cat extends Animal { @Override public void shout () { System.out.println("喵喵" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package Y24M12D31;public class Test007 { public static void main (String[] args) { Angel a1 = new Angel (); a1.fly(); a1.helpOthers(); } } interface Volant { int h = 100 ; void fly () ; } interface Honest { void helpOthers () ; } class Angel implements Volant ,Honest{ @Override public void helpOthers () { System.out.println("帮助他人" ); } @Override public void fly () { System.out.println("起飞" ); } }
数组和算法 一维数组
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package Y24M10D19;public class TestStatic { int id; static String company = "薯片责任有限公司" ; static int companyId = 0 ; static { System.out.println("类被初始化的调用" ); companyId = 111222 ; } static void printCompany () { System.out.println("公司信息" +company); } void login () { System.out.println("登录" ); } public static void main (String[] args) { TestStatic.printCompany(); TestStatic t1 = new TestStatic (); t1.login(); TestStatic t2 = new TestStatic (); t2.login(); } }
二维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package Y24M12D31;import java.util.Arrays;public class Test009 { public static void main (String[] args) { int [] [] a = new int [3 ][]; a[0 ] = new int [2 ]; a[1 ] = new int [4 ]; a[2 ] = new int [3 ]; a[0 ][0 ] = 10 ; a[0 ][1 ] = 20 ; a[1 ] = new int []{10 ,20 ,30 ,40 }; a[2 ] = new int []{10 ,20 ,30 }; int [][] b = { {10 ,20 ,30 }, {10 ,20 }, {100 ,200 ,300 ,400 } }; for (int i = 0 ;i<b.length;i++) { for (int m=0 ;m<b[i].length;m++) { System.out.print(b[i][m]+"\t" ); } System.out.println(); } for (int i=0 ;i<b.length;i++) { System.out.println(Arrays.toString(b[i])); } } }
package和import
排序算法 冒泡排序
不断做两两比较,可以从前往后,也可以从后往前,如果从前往后,那就是不断两两比较,如果大的就放到后面,第一轮结束之后可以找出最大的。
第一轮开始之前是这样
第一轮结束之后就是这样
最后的结果
代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package Y24M12D31;public class Test010 { public static void main (String[] args) { int [] values = {3 ,1 ,2 ,7 ,6 ,5 ,0 ,9 ,4 ,8 }; for (int tempo:values) { System.out.print(tempo); } System.out.println(); for (int i = 0 ; i<values.length;i++) { for (int j = 0 ; j<values.length-i-1 ;j++) { int tempo = 0 ; if (values[j]>values[j+1 ]) { tempo = values[j]; values[j] = values[j+1 ]; values[j+1 ] = tempo; } } } for (int tempo:values) { System.out.print(tempo); } System.out.println(); } }
选择排序 原理:每轮选择当前位置,开始找出后面的较小值与该位置交换 当前位置以此跟后面的比较,只要比他小的就交换
总共需要确定的轮数:数组长度-1 每一轮确定一个元素,下一轮减少一个个元素参与
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package Y24M12D31;import java.util.Arrays;public class Test011 { public static void main (String[] args) { int [] arr = {5 ,1 ,3 ,2 }; System.out.println(Arrays.toString(arr)); for (int i = 0 ;i<arr.length;i++) { for (int j=i+1 ;j<arr.length;j++) { if (arr[i] >arr[j]) { int temp= arr[i]; arr[i] = arr[j]; arr[j] = temp; } } } System.out.println(Arrays.toString(arr)); } }
二分查找 前提条件:数组中的数据必须是有序的 核心思想:每次排除一半的数据,查询数据的性能明显提高极多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 package Y24M12D31;public class Test012 { public static void main (String[] args) { int []arr = {1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10 ,100 ,200 ,300 ,400 }; System.out.println(arr[binSearch(arr,6 )]); } public static int binSearch (int [] arr,int number) { int left = 0 ; int right = arr.length-1 ; while (left <= right) { int mid = (left+right)/2 ; if (arr[mid]==number) { return mid; }else if (arr[mid]>number) { right = mid -1 ; } else if (arr[mid]<number) { left = mid +1 ; } } return -1 ; } }
课堂题目