一、 JVM、JRE、JDK三者的关系
JVM:java虚拟机(是一款软件),它是Java运行的载体(平台)
JRE:java的运行环境(只能运行已经存在的java程序,字节码),不能进行开发!【包含了JVM和核心类库】
JDK:java的开发环境【包含了JRE和开发工具包】<编译工具javac.exe、运行工具java.exe>)
JDK>JRE>JVM
二、常量
在程序运行过程中,数值不可改变的量
分类:
字符串常量:标志是双引号,双引号里面的内容是可以空着不写!
字符常量:标志是单引号,里面只能出现单个的字符 'A','0','我' 【单引号中必须有单个字符】
整数常量:标志是没有有小数点(与正负无关!),都是数字
小数常量:标志是有小数点(与正负无关!),都是数字
布尔常量:取值只有2个,true或者false
空常量: null 【不能直接打印】
三、数据类型
数据类型的出现是为了合理分配空间(数据最终是存放在jvm内存中的,不同的数据类型占据的空间是不一样的)
占据空间按照字节来计算!!!!每8个位(一个0或者一个1就是一个位)就等价于1个字节
分类:
基本类型:四类八种
整型:
byte 1个字节 short 2个字节 int 4个字节 long 8个字节
浮点型:
float 4个字节 double 8个字节
字符型:
char 2个字节
布尔型:
boolean 1个字节
引用类型:数组、类、接口
四、变量
变量:在程序运行过程中,数值可以改变的量
定义格式: 数据类型 变量名称 = 数值;
1、先定义,后赋值
int a;
a = 10;
2、在定义的同时直接赋值
int a = 10;
3、还可以一次性定义多个变量
先定义,后赋值
int x,y,z;
x = 10;
y = 20;
z = 30;
4、在定义的同时直接赋值
int x=10,y=20,z=30;
变量的操作:
取值:直接使用变量名,经常用于输出
修改值:变量名称=数值;
五、关键字
在java被被赋予了特殊含义的单词!
六、注释
对指定位置的程序进行描述,不参与程序执行的!
注释分类:
单行注释:// 注释内容
多行注释:/* 注释内容 */
文档注释:/** 注释内容 */
七、标识符
我们对 类、变量、方法名称取的名称!【标识符是自定义的】
使用标识符的命名规则:
硬性要求:
1.只能由字母、数字、下划线(_)、美元符号($)组成
2.不能以数字开头
3.不能是关键字
4.严格区分大小写
江湖规矩:
针对方法名称、变量需要遵循小驼峰命名规则
针对类名要遵循大驼峰命名规则
要见名知意!
八、数据类型转换
分类:
自动类型转换:小范围的数值赋值给大范围的变量
long number =1000;//将小范围int类型的数值1000赋值给大范围的long类型变量number【值不要超过int的最大取值范围】
规则:boolean类型不参与类型转换
byte---->>>short---->>>int---->>>long---->>>float---->>>double
char---->>>int---->>>long---->>>float---->>>double
强制类型转换:大范围数值赋值给小范围的变量
大范围的浮点数赋值给小范围的整数类型变量,此时会存在丢失精度问题
int number = 88.88; // 错误
int number = (int)88.88; // 正确,但是丢失精度,结果为 88
大范围的整数赋值给小范围的整数变量,此时可能存在数据溢出
九、运算符
包括:算术运算符、赋值运算符、自增自减运算符、关系运算符、逻辑运算符、三元运算符
==================>>>
算术运算符:+ - * / %
赋值运算符:= += -= *= /= %=
自增自减运算符:++ --
关系运算符:< <= > >= == !=
逻辑运算符:& | ! ^
短路逻辑运算符: && ||
三元运算符: boolean类型的表达式?结果1:结果2;
十、字符的 “+” 操作
System.out.println(2 + 'a'); // 99 ,说明字符'a'的数值是97
所有的字符都会有一个唯一的十进制的数值与之对应!=====>>> ASCII码表(里面记录了128个字符)
需要注意的三个字符对应的10进制数值
'0'---->>> 48
'A'---->>> 65
'a'---->>> 97
* 注意:
short byte char 只要进行算术运算,他都会先自动提升为int类型,然后参与运算!
十一、字符串的 “+” 操作
字符串在与[任意数据类型]用+号串联的时候都会进行拼接操作!
System.out.println(2 + "B"); // 2B ,字符串进行+操作,是在进行字符串拼接
System.out.println(2 + "B" + "啊,你"); // 2B啊,你
// 从左向右执行!
System.out.println(1 + 2 + "B" + "啊,你"); // 3B啊,你
System.out.println("哎" +1 + 2 + "B" + "啊,你"); // 哎12B啊,你
十二、键盘录入
为什么要有键盘录入? ===>>>为了让程序更加的灵活,达到人机交互的效果
如何实现键盘录入? ===>>>
总结:
第一步:导包
在自己定义的类上面书写 import java.util.Scanner; // 固定写法!
第二步:创建对象
Scanner scanner = new Scanner(System.in); // 只有scanner可以改变!!!
第三步:使用变量接收键盘录入的数据
int number = scanner.nextInt(); // scanner要与上面创建的对象的名称一致 (变量number可以修改)
十三、流程控制语句
分类:
顺序结构:没有固定的语法,程序从上向下依次执行!
分支结构:通过(if ,switch语句来实现) 【也称为选择结构或者判断结构】
循环结构:通过(for, while,do...while语句来实现的)
=======================>>>
分支结构 - if
单if语句的格式和流程:
格式:
if(关系表达式){
// 语句体
}
流程:
1.先执行关系表达式,得到的结果是一个boolean值(不是true就是false)
2.如果关系表达式的结果为true,那么就执行语句体;否则就不执行语句体
3.不论执不执行if语句里面的语句体,最终都会执行if语句下面的其它语句!
if-else语句的格式和流程:
格式:
if(关系表达式){
// 语句体1;
}else{
// 语句体2;
}
执行流程:
1. 先执行关系表达式,结果是一个boolean值!
2. boolean是true,就执行语句体1;否则就执行语句体2
3. 无论如何最终会按照顺序结构执行if语句下面的其它语句
if...else if...else语句的格式和流程:
if(关系表达式1){
// 语句体1
}else if(关系表达式2){
// 语句体2
}else if(关系表达式3){
// 语句体3
}else{
// 语句体4
}
执行流程:
首先计算比较表达式1看其返回值是true还是false,
如果是true,就执行语句体1,if语句结束。
如果是false,接着计算比较表达式2看其返回值是true还是false,
如果是true,就执行语句体2,if语句结束。
如果是false,接着计算比较表达式3看其返回值是true还是false,
如果都是false,就执行语句体n+1。
switch语句
格式:
switch(被检测的数据){ // 被检测数据一般是一个变量(有值)
case 数值1:
语句体1;
break;
case 数值2:
语句体2;
break;
case 数值3:
语句体3;
break;
......
default:
语句体n;
break;
}
执行流程:
执行被检测数据(它可能是一个表达式) 【当然它还可以是一个变量】
然后执行第一个case语句,拿着case的数值与被检测的数据进行匹配:
匹配上了,就执行该case里面的语句体,遇到break就结束switch语句。
未匹配上,就拿着第二个case的数值与被检测数据进行匹配:
匹配上了,就执行该case里面的语句体,遇到break就结束switch语句。
未匹配上,就拿着第三个case的数值与被检测数据进行匹配:
依次类推。。。。。。
若所有的case数值都与被检测数据不匹配,那么就执行default里面的语句体,遇到break结束switch语句。
注意事项:
switch里面的被检测数据的数据类型只能是: byte short char int 枚举 String
case取值:case的值必须是一个常量,case常量值的类型要有被检测数据的类型一致,case后面的值不允许重复!
case穿透现象:当我们在书写switch语句的时候,忘记书写break语句,那么此时就会发生case穿透现象!穿透case语句,那么它是
不做case值的匹配,直接进入下一个穿透的case语句体。结束:要么遇到break,要么就执行到switch语句的末尾
default的问题:default语句不论放在switch语句的哪个位置,它都不会先执行! 它永远先执行第一个case语句!只有当所有的case值都与被检测数据不匹配才会执行default语句!
default语句若放在switch语句的末尾,那么break语句可以省略不写!【default语句里面的break建议写上!】
default语法若不是放在switch语句的末尾,没有写break语句,依旧会发生穿透现象!
for循环
循环的特点:重复执行某个动作,有明确的开始和结束
1. for循环的格式
格式:
for(初始化表达式;条件判断语句;控制语句){
// 循环体;
}
解释说明:
①初始化表达式:确定循环的开始
②条件判断语句:确定循环的结束
③循环体:不断重复执行的功能!
④控制语句:又称之为步进!
整个循环执行的次数由 ①②④三部分来确定!!!
while循环
while循环的格式:
初始化语句;
while(条件判断语句){
循环体语句;
步进(控制语句);
}
while循环的执行流程:【与for循环完全一样的!】
先执行初始化语句;
然后执行条件判断语句:
结果为true:
它就会执行循环体语句
执行完循环体语句之后,就会执行步进(条件控制语句)
然后再执行条件判断语句:
如果条件为true,就再执行一次循环体,步进,接着执行条件判断语句,直到条件判断语句为false,它就结束while循环!
do...while循环
do...while循环的格式:
初始化语句;
do {
循环体语句;
条件控制语句;
}while(条件判断语句);
执行流程:
执行初始化语句;
执行循环体语句;
执行条件控制语句;
执行条件判断语句,看其结果是true还是false
如果是false,循环结束
如果是true,继续执行循环体、条件控制语句,再执行条件判断语句……
三种循环的区别:
for循环、while循环与do...while循环的区别 ===>>> do...while循环至少会执行一次循环体!
for循环和while的区别 ===>>> for循环无法获得里面的变量的值!while循环可以获得里面的变量值!
三种循环,for循环使用是最多的,在不明确循环次数的时候我们会是用while,do...while基本不怎么使用!死循环我们基本上使用的都是while死循环!
十四、跳转控制语句
break: 直接终止循环!【可用于循环、switch语句】
continue: 结束本次循环,进入下一次循环【只能在循环当中使用!】
十五、循环嵌套
在循环中,继续定义循环
例:打印九九乘法表
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) { // 控制行!(变量i代表行)
for (int j = 1; j <= i; j++) { // 控制列!(受行的控制!当前行的列数不得高于所在行号)
System.out.print(j + "x" + i +"=" + i *j + "\t"); // \t是一个制表符(相当于Tab键)
}
System.out.println("");
}
}
十六、Random随机数
第一步:导包
import java.util.Random; // 必须放在类的上面!
第二步:创建对象
Random random = new Random(); // 除了random这个变量名可以修改之外,其它的都是固定的!
第三步:获得随机数
int num = random.nextInt(10); // 获取0-9之间的数字 【num变量名可以修改,数值10可以修改,其余的固定】
获得1-100 : random.nextInt(100)+1;
十七、数组
1. 什么是数组?
它就是一个容器(能够存储数据),要求里面所有的数据的类型必须一致!
2.如何定义数组?
方式一:
数据类型[] 变量名称 推荐使用的!
方式二:
数据类型 变量名称[] 这种方式不推荐!
3.数组的初始化?
分为动态初始化和静态初始化!
动态初始化格式:
数据类型[] 数组名称 = new 数据类型[数组的长度];
例如:int[] array = new int[5];
解释:
等号左侧:
int: 定义的这个数组中所有元素的数据类型必须是int类型
[]: 数组的标志
array:数组名称
等号右侧:
new:在内存中创建一个数组(为这个数组在内存中申请一块空间)
int:定义的这个数组中所有元素的数据类型必须是int类型
[]:数组的标志
5:指定数组的长度(里面存放元素的个数)
静态初始化格式:
静态初始化的标准格式:
数据类型[] 变量名称 = new 数据类型[]{元素1,元素2,元素3,元素4,……};
例如: int[] array = new int[]{10,20,30,40};
静态初始化的简化格式:
数据类型[] 变量名称 ={元素1,元素2,元素3,元素4,……};
例如: int[] array = {10,20,30,40};
4.数组操作的两个问题:
1) 数组索引越界异常
ArrayIndexOutofBoundsException : 当访问了不存在的索引时【原因】
2)空指针异常 :
NullPointerException : 当一个变量不再记录地址值的时候, 还想去访问堆内存的数据.【原因】
5.数组遍历
数组的遍历, 就是通过[循环]将数组中所有的数据[取出来]【依旧依赖数组的索引值】
int[] array = {10,20,30,40};
for(int i=0;i<array.length;i++){
array[i];
}
十八、方法的定义和调用
1. 方法的基本定义和调用的格式:
定义格式:
public static void 方法名称(){
// 方法体
}
调用格式:
方法名称();
总结:
1. 方法不会自动执行,必须被调用才会执行! 【main是整个程序的入口】
2. 方法必须先定义,后调用;没有定义方法,就去调用就会报错!
3. 执行的结果与方法的定义顺序无关!与方法的调用顺序有关(谁先调用谁先执行)!
4. 方法定义在类的内部,其它方法的外部【不能在一个方法的内部再去定义另外一个方法】
带参数方法的定义和调用格式:
定义格式:
public static void 方法名称(参数列表){
}
1个参数:
public static void 方法名称(数据类型 变量名称){
}
多个参数:
public static void 方法名称(数据类型 变量名称1,数据类型 变量名称2,数据类型 变量名称3,……){
}
调用格式:
方法名(实际参数); // 实际参数它是要给数值!
形参和实参
定义方法的参数是 形式参数!
调用方法的时参数是 实际参数!【它可以是一个常量,也可以是一个变量】
带返回值方法的定义格式:
格式:
public static 返回值数据类型 方法名称(参数列表){
return 数值; // 这个数值必须是定义方法的里面的返回值类型!
}
带返回值方法的调用格式:
格式:数据类型 变量名称 = 方法名称(实参);
方法的通用格式为:
格式:
修饰符 返回值类型 方法名(参数列表){
// 参数列表:它是形式参数,由数据类型和变量名称,可以有0-N个,多个参数之间使用逗号隔开!
方法体;
return 返回值;
}
定义方法:2个明确(返回值数据类型、参数列表)
方法的调用:
没有返回值:直接调用
有返回值:直接调用、接收调用、打印调用
十九、方法重载
★ 多个方法必须在同一个类中
★ 方法名称必须完全相同
★ 参数列表必须不一样!(参数的个数,数据类型)
二十、方法参数传递基本数据类型和引用数据类型的区别
基本数据类型的参数,形式参数的改变,不影响实际参数的值!
对于引用类型的参数,形式参数的改变,影响实际参数的值
二十一、面向对象
面向对象与面向过程
面向过程:要想实现一个功能,我们必须清楚它的每一个实现步骤,必须亲力亲为!【都需我们自己完成】
面向对象:要想实现一个功能,我们并不需要自己清楚的知道实现细节,借助别人的(某个对象)功能
类与对象的关系
类是对某一类事物的抽象描述(这类事物具有相同的属性和行为),类是对象的数据类型,类是对象的抽象描述
对象是一个具体的事物,它是类的具体体现!
定义类的格式:
public class 类名{
// 成员变量
// 成员方法
}
对象的使用
对象的创建:
类名 变量名称(即对象名称) = new 类名();
对象访问成员变量:
在没有使用private修饰的时候,我们可以直接通过对象去访问
对象.属性名称 // 获取属性值
对象.属性名称 = 数值; // 设置属性值
对象访问成员方法:
对象.成员方法名称(实际参数);
二十二、成员变量与局部变量的区别:
作用域:
成员变量:在整个类中!
局部变量:在当前的方法内部或者代码块中
定义的位置:
成员变量 : 定义在类中方法外
局部变量 : 定义在哎方法内部或者是形式参数位置
内存的位置:
成员变量:在堆内存中
局部变量:在栈内存中
生命周期:
成员变量:随着对象的创建而存在,随着对象的销毁而消失
局部变量:随着方法的执行而存在,随着方法执行结束而消失
初始值:
成员变量:有初始值
局部变量:没有初始值,必须先赋值才能使用!
二十三、private关键字
特点:
但凡被private修饰的内容只能在本类中使用!【private修饰的内容也是封装的一种体现】
作用:
保证成员变量的安全!
二十四、this关键字
使用场景:
成员变量和局部变量重名,为了避免局部变量隐藏了成员变量
代表的含义:
this代表本类的一个实例对象
谁调用方法,那么在这个方法中,this就代表谁!
二十五、String类
String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例(对象)。
只要使用双引号包裹起来的内容都是String类的一个实例对象!
也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象。String 类在 java.lang 包下,所以使用的时候不需要导包
特点:
1. 字符串一旦创建,那么它的内容不可更改!
2. 字符串里面的数据是可以共享的!
3. 字符串的底层是字节(数组)
String类的创建方式的区别
通过构造方法:
char[] chs = {'a','b','c'};
String str1 = new String(chs); // 在堆内存,开辟一个新的空间
String str2 = new String(chs); // 在堆内存,开辟一个新的空间
str1和str2的地址值是不同的!但是里面的数据是一样的!
直接赋值:
String str3 = "abc"; // 在堆内存中的常量池中
String str4 = "abc"; // 在堆内存中的常量池中
str3和str4的地址值是一样的,数据也一样【共享数据】
String类的常用方法:
== 对于基本类型比较的是数值,对于引用类型比较的是地址值
boolean equals(String str); // 比较两个字符的数据内容是否相同
char charAt(int index); // 获得字符串中指定索引位置的字符
int length(); // 获得字符串的长度
char[] toCharArray(); // 将字符串转成字符数组
boolean equalsIgnoreCase(String anotherString); // 比较2个字符串的内容是否相同,忽略大小写
boolean constains(CharSequence c); // 判断一个字符串是否包含指定内容
二十六、StringBuilder
构造方法:
StringBuilder();
StringBuilder(String str); // 将一个字符串转成StringBuilder
功能方法:
StringBuilder append(String str); // 在之前StringBuilder的末尾添加str
StringBuilder reverse(); // 将StringBuilder里面的数据反转
String toString(); // 将StringBuilder转成String
二十七、ArrayList集合
什么是集合
它是一个容器,将一类数据可以存放进去。长度可变!!!
ArrayList集合的特点
可以对里面的数据进行增删改查操作!它的底层就是数组!长度可变!
增删效率低!、查询和修改效率高!
增加:先将数组进行扩容(默认是当前数组的1.5倍),将之前数组里面的数据给它赋值到这新数组(集合)中去,再把要添加的元素追加到新数组的后面
删除:一旦删除某个索引位置的元素,那么后面所有的元素都要进行一个整体的位置
查询、修改:根据索引直接就非常方便的完成!
泛型的使用
泛型:用于约束当前集合对象里面存放的数据的数据类型!
集合与数组的区别
数组的长度是固定的! int[] array = new int[6]; //长度固定为6
集合的长度是可变的!
ArrayList<E> students = new ArrayList<E>();//【只能给引用类型(类、数组),不要给基本数据类型】
ArrayList<Student> students = new ArrayList<Student>();
如果非要存储基本类型的数据,那么泛型需要给基本类型对应的包装类:
int Interger
char Character
byte Byte
short Short
long Long
float Float
boolean Boolean
double Double
功能方法:
方法名 | 说明 |
---|---|
public boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
public boolean add(E e) | 将指定的元素追加到此集合的末尾 |
public void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |