JavaSE基础
一、Java基础知识
1、JVM ——java虚拟机
主要解决的是各种操作系统平台不同产生的差异化,与普通在window运行的虚拟机相似,主要是只可以运行java语言。
JVM相当于计算机的硬件,并且只需要基本的CPU和内存,而内存在JVM上分为五大模块:
①、程序计数器,与计算机原理中的PC类似,就是记录代码执行到那个地方,相当于路标。
②、虚拟机栈,与程序计数器进行配合,即如何寻到下一需要执行的地方。
③、 本地方法栈
④、堆
⑤、方法区+元数据区
2、Jre——java运行时环境
上诉的JVM只是提供了舞台(硬件),还需要软件去运行java程序,而Jre就是运行java程序所必须环境的集合。Jre与JVM是包含关系JVM<Jre.
3、JDK——java开发者工具
JDK提供了Java的开发环境,如编译器javac,用于将java文件编译为class文件,并且提供运行环境,即JVM,使得class文件得以运行。其JDK、Jre、JVM关系如下图所示,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gH7V1IY-1617612467393)(C:\Users\11141\AppData\Roaming\Typora\typora-user-images\image-20210322195624259.png)]
二、java程序的编写
1、类名(class的命名规则)
类名(标识符)定义的法律:
①、只允许大小写字母、数字、下划线、美元符号作为类名合理部分存在,其他内容的出现会导致错误
②、不允许使用数组开头,不允许有全数字的类名
编程规范(道德):
①、遵循大驼峰命名法
②、类中尽量出现数字、_和$
③、不要使用中文作为类名
④、类名最好不超过十五个字符,如果单词长度过长,使用缩写
重名与Public:
①、若类名前有public修饰,则java文件的名字必须与类名相同
②、无论什么情况类名都不允许重名,但一个java文件中可以有多个类,但public修饰的类只能有一个或者没有。
2、截断符:{}、;
{}:代表将多行代码,统一成一个代码块,以{开始统计,以}结束统计
; :代表一行代码的结束,如果之前的 内容不是{,那么就应该以;结束这一行
3、变量
局部变量:声明在方法里面的变量
变量的声明需要符合一定的格式:类型 标志符;
对于变量的声明过程,必须先声明,再使用,如果是局部变量,还需要一个赋值的过程,同时我们有一个在声明的同时赋值的过程,其格式:
类型 标识符(小驼峰命名法) =字面量
4、类型
JAVA之所以被称为语言,是因为他和其他的自然语言很相似,我们去了解一下自然语言,比如说,英语
整型:byte (1字节) short(2字节) int(4字节) long(8字节)
eg:byte b = 127;
byte:-128~127 ,因此++b就会产生溢出,得到-128的答案。
short:-215~215-1
int:-231~231-1
long:-263~263-1
并且整型中可以小往大转,即byte->int,而大往小转可以通过强制转换,但这会使得溢出,即 int b=384;s=(byte)b。其 s=-128,前面的256直接舍去,变成1000 0000 ,即-128.
浮点型:float(4字节)、double(8字节)
why not 小数型 —— 计算机表示问题(二进制无法精确表示小数,eg:0.3),即金融行业不会采用浮点型进行运算,这些不精确的运算会导致大量利益损失。eg,微信支付中可以支付小数的原因是因为在微信中的换算单位是分,因此相当于整数。
并且由于编辑器的原因,遇到的数字会自动先转为int,因此声明时为:
float f = 4.5f;
float f1 = (float)3/5; 若没有强转,则f1为0。
字符型:char(2字节)
char c = '1';//ascll中‘1’为49,注意Ascll码
byte b = 49;
char c1 = 49;
char c2 = 26446;
布尔类型:boolean(动态字节-一个布尔类型4字节“底层用C语言写”,但在用数组的布尔时为1字节)
boolean flag = true; //无法用1、0代替true、false
三、Java语言语义与语法
1、表达式(语法)
表达式:通过将标识符,运算符和字面量按照一定的规则,结合到一起,得到一份结果的式子,叫做表达式。
eg: a = 3 也是表达式,只要能得出结果就行
2、算术运算符
+、-、、/、%、++、–、+=、-=、/=、*=*
易误点:
①、除号/ :有三种情况的发生:无法编译、Infinity、NaN(Not a Number)
整数时:除数为0时无法编译,且0/0也是无法编译
被除数为浮点数时:
float a = 4/3;
System.out.println(a/0);//Infnity : 无限
System.out.println(0f/0); //NaN : Not a Number
②、++、–符
首先在使用的时候可以看做a++相当于先使用a,再a=a+1;++a相当于先a=a+1,再使用a。
byte g = 127;
System.out.println(g-- - --g); //127-125=2
但是在Java中,a++与a=a+1 的区别,a++为在原来的地址上自增1,而a=a+1更改了地址,=相当于指针,类型不可转换,a+1为int
System.out.println(g+3); //可以运行,没有=,不会赋为int,因此不报错
System.out.println(g+=3); //-126 不改变原来地址
3、位运算符
对操作整型数字直接中的位而存在的运算符
>>(右移,符号位不变)、<<(左移,符号位不变)、>>>(向右移,补的全是零)、&(同一为一,其余为零)、|(同零为零,其余为一)、^(异或)、~(非,0->1,1->0)
易误点:
①、>>与>>>的区别
正数时:两个符号都是向右移动,而且补全的全是0,对结果影响不大
负数时:>>右移,当前符号位为1,而现在补全的还是1,因此任是负数。而>>>右移是,补全的一直为0,所以会变成正数。
②、&
同一为一,其余为零:可以用来求出余数(2的倍数时),即相当于%的作用,进行二进制按为与时可以将除数作为其二进制最后的余数位。
eg: 773: 0011 0000 0101 ,其16的余数应是 0101
即和 0000 0000 1111 进行与运算,即可得出余数
相当于 773 & 15
4、关系运算符
==、!=、>、<、>=、<=
int x = 'c';
char y = 'c';
System.out.println(x == y);
只需注意这里为True,ASCII码
5、逻辑运算符
&&(短路与)、||(短路或)、&、|、!
&与&&的区别(|与||类似):
&的两边都必须编译计算,然后进行判断T or F
&&则为短路与,当第一个表达式为 F 时,则可以确定其最后一定为 F,所以不再计算第二个表达式
eg:
int a = 5;
System.out.println(3>4&&a++>2);
System.out.println(a);
其输出为:false 、5
6、特殊运算符
一般这种运算符,只有一个这样的运算符
优先级运算符:()
赋值运算符:=
7、三目运算符
boolean?分支1:分支2 (true执行分支1,false执行分支2)
8、优先级
() > 算术 > 位运算 > 关系 > 逻辑 > =
单目运算符>多目运算符
ps: 当模糊时,最好进行简单测试
级别为 1 的优先级最高,级别 11 的优先级最低。
四、流程控制
1、简述
在没有流程控制之前,代码的执行顺序是依次从上到下,从左到右执行的。流程控制,可以在一定的程度上,改变代码的执行顺序,跳过部分代码或重复部分代码都是流程控制的作用。
常见的流程控制有 if,for,switch,while,do…while
把常见的流程控制分成两个大类,分别是分支和循环
2、分支类别
分支使用的关键字有两个 if 、 switch
if 分支
其格式是 if(boolean) {code} ,注:没有else if关键字,但可以使用。
if(2>1){
System.out.println("T");
}else {
System.out.println("F");
}
//下面的格式,大括号可以省略,但如果没有大括号,那么code只能有一行代码,第二行代码都会被认为不在if过程中
if(2>1) System.out.println(a);
switch分支流程
switch的格式
switch(标志符){
case目标值:
code
case目标值:
code
case目标值:
code
case目标值:
code
…
default:
code
}
int b = 2;
switch(b) {
case 1:
System.out.println("1");
break;
case 2:
System.out.println("2");
break;
default:
System.out.println("I don't know");
}
易错点:
整型中long不可放入switch,太长
浮点型不可放入switch,无法精确
布尔型不可放入switch,无法从boolean->int
即switch里头的标识符内最多4字节,且可以与int互转,eg: char、byte、short
switch 且可以放String,java7以后可以,之前不行
switch针对离散型变量进行流程控制
if连续、离散都可以
3、循环
当条件被满足的时候,重复执行某一个部分的代码
for while do…while 递归
for循环的格式 for(1;2;3){4}
1:初始化部分,可以省略,含义是只有在for循环第一次开始的时候,才会执行1部分的代码
2:条件判断部分,默认是必然成立的,每一次循环完成,准备开始下一次循环之前必然需要执行一遍2部分代码
3:条件改变部分,每次循环的代码块执行完成以后,后先执行3部分的代码来改变循环条件。
4:循环的代码块
int sum=0;
for(int i=1;i<=100;i++){
sum += i;
if(sum >= 1000){
sum-=i;
break;
}
}
System.out.println(sum);
注意可以有嵌套:
for(int i = 1;i <= 6;i++ ) {
for(int j = 1;j <= i;j++)
System.out.print("*");
System.out.print("\n");
}
while循环
格式:
while(boolean) {code}
eg:
int i = 4;
int e = 0;
boolean flag = false;
while(!flag){
System.out.println("Eat");
e++;
if(e>=i){
flag = true;
}
}
for(int m = 0;m < 4;m++)
System.out.println("Eat");
注:主要就是当没有具体循环次数时,而又明显判断返回boolean时用while循环,有具体次数一般用for循环。
五、数组
1、概述
数组是一个连续不断的内存空间,用来保存相同类型内容的一个容器。不允许超出脚标范围,会抛出异 常,ArrayIndexOutOfBoundsException
2、格式
类型[] 标识符;
可以将类型[]看做一种新类型去理解
eg: int[] array = new int[6];
一般数组的大小在确定后不能随便改变
but,改变数组大小的方式,是指向另一片更大的内存,eg:
array = new int[10]; 原来的值都不存在,已经变到其他地方了。
3、初始化
动态初始化
array = new int[10];
array[0] = 23456;
只设定长度,通过动态赋值给数组。一般可以用遍历。
静态初始化
int[] array= {8,2,6,4,9,1,5};
直接在定义时便赋值
4、容器
数组为我们学到的第一个容器
容器的操作:定位(1、知道元素找到在容器的位置、2、知道容器找到元素在容器的位置)、替换、求长
通过这些操作我们可以解决许多问题,eg:遍历(定位+求长) PS: array.length 代表其array数组的长度
斐波那契数列:1,1,2,3,5,8,13 . . . . . . .
实现:
int[] Fei = new int[20];
Fei[0] = 1;
Fei[1] = 1;
for(int i = 2;i<Fei.length;i++){
Fei[i] = Fei[i-1] + Fei[i-2];
}
System.out.println(Fei[19]);//输出第二十个数列值
直接排序:每一轮交换出最小(大)值
实现:
for(int i = 0;i<arrayOne.length;i++){
for(int j = i;j<arrayOne.length;j++){
if(arrayOne[j] < arrayOne[i]){
int change;
change = arrayOne[i];
arrayOne[i] = arrayOne[j];
arrayOne[j] = change;
}
}
}
选择排序:每一轮选出最小(大)值,只标记,最后才替换
实现:
for(int i = 0;i<arrayOne.length;i++){
int minIndex = i;
//int minValue = arrayOne[i];
for(int j = i;j<arrayOne.length;j++){
if(arrayOne[minIndex] > arrayOne[j])
minIndex = j;
// minValue = arrayOne[j];
}
int tmp = arrayOne[minIndex];
arrayOne[i] = arrayOne[minIndex];
arrayOne[minIndex] = tmp;
}
冒泡排序:相邻判断,每轮在最后得出最大值
实现:
for(int i = 0;i<arrayOne.length;i++){
for(int j = 0;j<arrayOne.length-1-i;i++)
if(arrayOne[j]>arrayOne[j+1]){
int tmp = arrayOne[j];
arrayOne[j] = arrayOne[j+1];
arrayOne[j+1] = tmp;
}
}
5、二维数组
概念
二维数组本质上是以一维数组作为数组元素的数组,即“数组的数组”。在堆内存存放是每个一维数组并不连续,但其每个一位数组的开头都寄放在一个连续的一位数组上,实现逻辑连续。
类型,标志符
int[][] array = new int[10][10];
赋值时与一维数组一样,具有静态赋值和动态赋值。
but 列中可以不赋值,每一行都是NULL
int[][] array = new int[10][];
遍历
采用嵌套for循环
for(int i = 0;i<array.length;i++){ //array.length 为有多少行
for(int j = 0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
六、关键字
关键字,关键字,是java中具有一定含义的描述词
这些描述词,不能当做变量名出现,所以我们叫这些词,关键字
其中之前我们学习的循环分支中的if、for、while、do、switch等都是关键字
关键字在代码中的特点是写完以后会变得高亮
比如:
int
易误点:
String、Scanner等都不是关键字
//可以这样定义
int String = 4;
//但不可以 String int = “ ”
采用嵌套for循环
for(int i = 0;i<array.length;i++){ //array.length 为有多少行
for(int j = 0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}