目录
1. java概述
1.1 JVM JRE JDK
2. 基础语法
2.1 注释
2.2 关键字
2.3 常量
2.4 数据类型
2.5 变量
2.6 标识符
*2.7 类型转换
2.7.1 隐式转换
2.7.2 强制转换
2.7.3 常量优化机制
3. 运算符
3.1 算数运算符
3.2 赋值运算符
3.3 自增自减运算符
3.4 关系运算符
3.5 逻辑运算符
3.6 短路运算符
3.7 三元运算符
4. 方法
4.1 方法概述
4.2 方法的定义和调用
4.3 带参数方法的定义和调用
4.4 方法的注意事项
4.5 方法重载
4.6 *方法的参数传递
5. 分支语句
5.1 流程控制
5.2 顺序结构
5.3 if语句
5.4 switch语句
6. 循环语句
6.1 for循环语句
6.2 while循环语句
6.3 do...while循环语句
6.4 三种循环的区别
6.5 Random
7. 数组
7.1 数组定义格式
7.2 数组初始化
7.2.1 数组静态初始化
7.2.2 数组动态初始化
7.2.3 两种初始化比较
7.3 java中内存分配(参考4.6)
7.4 数组操作的两个常见问题
7.4.1 索引越界(ArrayIndexOutOfBoundsException)
7.4.2 指针异常(NullPointerException)
8 二维数组
8.1 二维数组初始化格式
8.1.1 二维数组静态初始化
8.1.2 二维数组动态初始化
8.2 二维数组内存空间
9 面向对象基础
9.1 类和对象
9.2 对象内存图
9.3 成员变量和局部变量
9.4 this关键字
9.5 权限修饰符
9.5 构造方法
9.6 封装
JDK(Java Development Kit):java开发工具包,jdk17.0.6版本,包含了JRE、编译器以及许多调试、分析等工具软件。它能够创建和编译Java程序 。
JVM(Java Virtual Machine):即Java虚拟机,用来运行Java字节码文件,JVM是Java跨平台的关键。因为它屏蔽了不同操作系统之间的差异,可以让相同的Java程序在不同的操作系统上运行出相同的结果。
JRE(Java Runtime Environment):即Java运行时环境,它是运行Java已编译程序所必需的软件环境,包含了JVM、Java标准类库。JRE提供给只想运行Java程序的用户使用,不能用于创建新的程序,即不能将Java源代码编译程字节码文件。
(1)计算机存储单元:计算机存储设备的最小信息单元是“位(bit)”,又称为比特位,常用小写字母“b”表示。计算机中最小的存储单元是“字节(byte)”,通常用大写字母“B”表示,字节是由连续的8个位组成。其他常用的存储单位如下:
1B = 8bit;
1KB = 1024B;
1MB = 1024KB;
1GB = 1024MB;
1TB = 1024GB
(2)数据类型:Java语言是强类型语言
整数
byte 1字节
short 2字节
int 4字节
long 8字节 使用需要加L标识 long num = 12345678L;
浮点数
double(双精度) 8字节
float(单精度) 4字节 使用需要加入F标识 float num = 12.3F;
布尔类型
boolean 1字节
(1)概念:标识符是给类、方法、变量等起名字的符号。
(2)标识符定义规则:
*由数字、字母、下划线和美元符组成;
*不能以数字开头;
*不能是关键字;
*要区分大小写
(3)常见命名约定:
*小骆峰命名法:方法、变量
**约定1:标识符是一个单词的时候,首字母小写;
**约定2:标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写;
*大骆峰命名法:类
**约定1:标识符是一个单词的时候,首字母大写;
**约定2:标识符由多个单词组成的时候,每个单词的首字母大写;
(1)java的类型转包括隐式转换和强制转换,常量优化机制;
:把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。
//这里用一个比double类型小的数值,去赋值。整数型比浮点型范围小
double d = 12; //整数12默认为int型
System.out.println(d); //结果:12.0 结果显示从int类型的整数,变成了double类型的小数
//由此可得,小的数据类型直接赋值给大的,类型会提升,所以隐式类型转换也叫自动类型提升
:把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。
double num1 = 5.5;
int num2 = (int) num1; // 将double类型的num1强制转换为int类型
System.out.println(num2); // 输出5(不是4舍5入,而是小数位直接舍弃)
: 参考blog
(1)当 ‘+’ 操作中出现字符串时,这个 ‘+’ 是字符串连接符,而不是算术运算;
(2)在 ‘+’ 操作中,如果出现了字符串,就是连接运算符,否则就说算术运算。当连续进行 ‘+’ 操作时,从左到右逐个执行。
格式:关系表达式?表达式1:表达式2
计算规则:首先计算关系表达式的值,如果值为true,表达式1的值就是运算结果;如果值为false,表达式2的值就是运算结果。
/*
方法重载:
多个方法在同一个类中;
多个方法具有相同的方法名;
多个方法的参数不相同,类型不同或者数量不同
与返回值无关,在调用方法的时候,Java虚拟机会通过参数的不同来区分同名的方法
*/
public class MethoDemo
{
public static void main(String[] args)
{
//调用方法
int result = sum(a:10, b:20);
System.out.println(result);
double result2 = sum(a:10.0, b:20.0);
System.out.println(result2);
int reslult3 = sum(a:10, b:20, c:30);
System.out.println(result3);
//需求1:求两个int类型数据和的方法
public static int sum(int a, int b)
{
return a + b;
}
//需求2:求两个double类型数据和的方法
public static int sum(double a, double b)
{
return a + b;
}
//需求3:求三个int类型数据和的方法
public static int sum(int a, int b, int c)
{
return a + b + c;
}
}
(1)按值传递:值传递是当方法被调用时把实际参数,传给形式参数。这个是只是一个数值的传递,把实际参数的数值拷贝给形式参数,如果这个是时候形参发生改变那么拷贝的值也会发生改变,但是实际参数不会改变。因此形参的改变不会影响实际参数的改变。
值传递的适用数据类型:
1.八大基本数据类型(byte,short,int,long,char,float,double,boolean)
2.String类型
(2)引用传递:当方法调用时,实际参数的引用(地址)会传给形式参数,通过这个引用找到变量(在这里是对象)的真正地址,然后对地址中的值修改,所以对引用的操作等于对其指定的对象进行操作。
适用范围:
除String以外的数据类型的对象
/*
格式说明:
(1)表达式:取值为byte, short, int, char, string.
(2)case:后面跟的是要和表达式进行比较的值。
(3)break:表示中断,结束的意思,用来结束switch语句。
(4)default:表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似。
*/
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
···
default:
语句体n+1;
[break;]
}
作用: 产生一个随机数。
使用步骤:
(1)导包:import java.util.Random;
(2)创建对象:Random r = new Random();
(3)获取随机数:int number = r.nextInt(10); //获取数据的范围:[0,10],包括0,不包括10
示例:
/*
Random
*/
import java. util.Random
public class RandomDemo{
public static void main(String[] args){
//创建对象
Random r = new Random();
//用循环获取10个随机数
for(int i=0; i<10; i++){
//获取随机数
//Random的nextInt(int n)生成的随机整数范围是0到n之间,不包括n。所以以后如果想要生成随
//机数多少,直接可以通过控制参数来设定。
int number = r.nextInt(10);//随机生成[0,10)之间的整数
System.out.println("number:" + number);
//需求:获取一个1-100之间的随机数
int x = r.nextInt(100) + 1;//随机生成[1,101)之间的整数
System.out.println(x);
}
}
}
概念:数组(array)是一种用于存储多个相同类型数据的存储模型
数组的定义格式:
(1)格式1:数据类型[ ] 变量名,例如:int [ ] arr。定义了一个int类型的数组,数组名是arr。
(2)格式2:数据类型 变量名[ ], 例如:int arr[ ]。定义了一个int类型的变量,变量名是arr数组。
静态初始化:初始化时指定每个数组元素的初始值,由系统决定数组长度。
格式1:数据类型 [ ] 变量名 = new 数据类型[ ] {数据1, 数据2, 数据3, …}
int [ ] arr = new int[ ] {1, 2, 3};
格式2:数据类型 [ ] 变量名 = {数据1, 数据2, 数据3, …}
int [ ] arr = {1, 2, 3};
动态初始化:初始化时只指定数组长度,由系统分配默认初始化
动态初始化格式:数据类型 [ ] 变量名 = new 数据类型[数组长度]
public class ArrayDemo{
public static void main(String[] args){
int[] arr = new int[3];
/*
左边:
int:说明数组中的元素是int类型
[]:说明这是一个数组
arr:这是数组的名称
右边:
new:为数组申请内存空间
int:说明数组中的元素类型是int类型
[]:说明这是一个数组
3:数组长度,其实就说数组中的元素个数
}
}
系统分配默认初始化:
整数 | 0 | |
小数 | 0.0 | |
布尔 | false |
|
字符 | '\u0000' | Unicode字符,常见的体现是空白字符 |
引用数据类型 | null | 引用数据类型:数组、类(String)、接口 |
public static void arrayTest(){
String[] arr = new String[3];
for(int i =0; i
(1)区别:
动态初始化:手动指定长度,系统分配默认初始化
静态初始化:手动指定元素,系统根据元素个数来计算数组的长度
(2)选择:
静态初始化:如果要操作的数据,需求中已己经明确给出了,直接静态初始化
例子:需求:已知出缓学生成绩为100 100 90 20 100,找出最高分动态初始化:只明确元素个数,不明确具体数值
方法区:字节码文件加载时进入的内存,字节码文件(.class)由java源文件(.java)编译而成。
栈内存:方法运行时所进入的内存,也就是存储局部变量,定义在方法中的变量,使用完之后立刻弹出。
堆内存:存储new出来的内容(实体,对象),new出来的东西会在这块内存中开辟空间并产生地址。使用完毕,地址会被回收。
(1)例子1(静态数组/引用传递)
- JVM自动寻找main方法,执行第一句代码,创建一个int型的静态数组arr,在栈中分配一块内存,存放一个指向堆区对象的指针0x10f87f48,由于是静态数组可以直接指定每个数组元素的初始值
- 执行第二句代码:根据arr指向的地址修改arr[0]的值为44
- 执行第三句代码:根据arr指向的地址修改arr[1]的值为55
- 执行第四句代码:根据arr指向的地址修改arr[2]的值为66
- 执行第四句代码:根据arr指向的地址输出arr[0]的值为44
- 执行第五句代码:根据arr指向的地址输出arr[1]的值为55
- 执行第六句代码:根据arr指向的地址输出arr[2]的值为66
- 执行完毕栈内存中所有变量弹出
(2)例子2(值传递)
- JVM自动寻找main方法,执行第一句代码,创建一个int型的变量number,在栈中分配一块内存:int number = 100
- 执行第二句代码,打印语句:调用chang方法前:100
- 执行第三句代码,调用change方法,压入change(number),为change函数开辟一个新的栈内存空间
- change方法是含形参的,形参对于内存而言是变量,而变量在内存中占有空间。因此change方法里面创建一个int型的变量number, 在栈中分配一块内存:int number = 100,此时number是由main里面接收而来。
- 接下来走change函数里面的逻辑,change里面将number修改为200
- change(number)使用完毕没有逻辑了,弹栈消失
- 继续执行,打印语句,仍是主方法中的number值
- 所有逻辑完成,main弹栈消失
(3)例子3(利用返回值修改值传递)
- JVM自动寻找main方法,执行第一句代码,创建一个int型的变量number,在栈中分配一块内存:int number = 100
- 执行第二句代码,打印语句:调用chang方法前:100
- 执行第三句代码,调用change方法,压入change(number),为change函数开辟一个新的栈内存空间
- change方法是含形参的,形参对于内存而言是变量,而变量在内存中占有空间。因此change方法里面创建一个int型的变量number, 在栈中分配一块内存:int number = 100,此时number是由main里面接收而来。
- 接下来走change函数里面的逻辑,change里面将number修改为200,并且返回number值,此时main里面的number值被修改为200
6. 接下来走change函数的逻辑已经结束,弹栈消失
7. 继续执行,打印语句,打印主方法中的number值,此时的number值由于change的返回值已经变成了200
8. 所有逻辑完成,main弹栈消失
(4)例子4 (引用传递)
常见:二分法求middle的时候
解决方法:
middle = (left + right) / 2; //易发生索引越界
middle = left + (right - left) / 2;
格式:数据类型[ ][ ] 数组名 = new数据类型[ ] [ ]{{元素1,元素2},{元素1,元素2}};
int[][ ] arr = new int[][]{{11,22},{33,44}};
简化格式:数据类型[ ][ ] 数组名 = {{元素1,元素2},{元素1,元素2}};
int[][]arr = {{11,22},{33,44}};
细节:二维数组在存储一维数组的时候,具体存储的是一维数组的地址值,详见8.2内存空间
格式:数据类型[ ][ ] 数组名= new 数据类型[m][n];
m表示这个二维数组,可以存放多少个一维数组
n表示每一个一维数组,可以存放多少个元素
int[][] arr = new int[2][3];
解析:自用_哔哩哔哩_bilibili-, 视频播放量 3、弹幕量 0、点赞数 0、投硬币枚数 0、收藏人数 0、转发人数 0, 视频作者 sueiie, 作者简介 ,相关视频:睡觉用的,存档,【自用侵删】三分钟热身+十分钟帕梅拉内啡肽+八分钟拉伸,一菲声控洗头2,菲妈又来洗头,(椰子,哈密瓜,运动器材,西瓜)自剪自用,导尿 考试自用,【自用】《独家记忆》,「自用」考了满分就快乐回家吧!,健身气功五禽戏完整版-带呼吸法口令版 自用 侵删,「刘逗逗不怎么逗」3.0(自用)夏日版,自用白噪音https://www.bilibili.com/video/BV1wj411V7nj/?spm_id_from=333.999.0.0&vd_source=d4e211cee3c934f5b0d04c9b8d73b9f3
1. 什么是对象:万物皆对象,客观存在的事物皆为对象。
2. 什么是对象的属性: 对象具有的各种特征,每个对象的每个属性都拥有特定的值。
3. 什么是对象的行为: 对象能够执行的操作。
4. 什么是类:类是对现实生活中一类具有共同属性和行为的事物的抽象,确定对象将会拥有的属性和行为。类是JAVA程序的基本组成单位。
类的特点:
(1)类是对象的数据类型;
(2)类是具有相同属性和行为的一组对象的集合。
5. 类和对象的关系:类是对象的抽象,对象是类的实体。
创建对象:
类名 对象名 = new 类名();//有new进堆,开辟空间,产生地址
6. 类的组成:属性和行为。
属性:在类中通过成员变量来体现(类中方法外的变量)
行为:在类中通过成员方法来体现(和前面的方法相比去掉static关键字即可)
- 寻找main函数(在TestStudent类中),TestStudent类进入方法区;
- new一个Student类,由于调用了Student类,对其进行编译产生class文件,因此Student类进入方法区;
- 有new进堆,开辟空间,产生stu的地址,堆内存空间根据类所声明的成员变量默认初始化值,以及成员方法的引用地址
- 打印stu,此时打印的是stu的地址
- 打印stu的name值,此时打印的是默认初始值
- 打印stu的age值,此时打印的是默认初始值
- 将“张三”赋给stu的name值,根据stu地址找到name并修改
- 同上
- 打印修改后的name值
- 同上
- 根据stu地址找到stu.study()的地址,打印
- 根据stu地址找到stu.eat()的地址,打印
将stu1赋值给stu2,也就是将stu2指向和stu1一样的地址,后续无论是stu1还是stu2,只要对这个地址里面的变量修改,里面都会发生改变。
(1)成员变量:类中方法外的变量。
(2)局部变量:类中方法中的变量。
(3)成员变量和局部变量的区别:
(1)this关键字代表当前类对象的引用(地址),方法被哪个对象调用,this就代表哪个对象。
(2)this关键字调用本类成员变量:
方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量;
方法的形参没有与成员变量同名,不带this修饰的变量指的是成员变量。
(3)this.本类成员方法():没有前提条件,this可以省略
(4)this关键字也可以用于在构造函数中调用其他构造函数。但是,只能定义在构造函数的第一行,因为初始化动作要先执行。如:
class Person
{
private String name;
private int age;
Person()
{
name = "baby";
age = 1;
System.out.println("Person run");
}
Person(String name)
{
//成员变量和局部变量重名,可以用关键字this区分
this.name = name;
}
Person(String name,int age)
{
//调用其他构造函数时,只能定义在构造函数的第一行,因为初始化动作要先执行
this();
this.name = name;
this.age = age;
}
public void speak()
{
System.out.println(this.name+":"+this.age);
}
}
class ThisDemo
{
public static void main(String[] args)
{
Person p = new Person("小强",10);
p.speak();
}
}
private | 同一个类当中 |
(default) | 同一个类中,同一个包中 |
protected | 同一个类中,同一个包中,不同的子类(继承) |
public | 任意位置访问 |
- 如果没有定义构造方法,系统会给出一个默认的无参构造方法
- 构造方法允许重载关系出现
封装原则:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxx() / setXxx()方法。
String
中的对象是不可变的。String
类型进行改变的时候,都会生成一个新的 String
对象,然后将指针指向新的 String
对象。 String s1 = "abc";
s1 = "def";
//abc和def在常量池的不同位置
字符串常量池:是 JVM 为了提升性能和减少内存消耗针对字符串(String 类)专门开辟的一块区域,主要目的是为了避免字符串的重复创建。
(1)采用字面值的方式创建字符串对象
public class StringTest1 {
public static void main(String[] args) {
String str1="aaa";
String str2="aaa";
System.out.println(str1==str2);
}
}
运行结果:
true
采用字面值的方式创建一个字符串时,JVM首先会去字符串池中查找是否存在"aaa"这个对象,如果不存在,则在字符串池中创建"aaa"这个对象,然后将池中"aaa"这个对象的引用地址返回给字符串常量str,这样str会指向池中"aaa"这个字符串对象;如果存在,则不创建任何对象,直接将池中"aaa"这个对象的地址返回,赋给字符串常量。
对于上述的例子:这是因为,创建字符串对象str2时,字符串池中已经存在"aaa"这个对象,直接把对象"aaa"的引用地址返回给str2,这样str2指向了池中"aaa"这个对象,也就是说str1和str2指向了同一个对象,因此语句System.out.println(str1== str2)输出:true
(2)采用new关键字新建一个字符串对象
public class StringTest2 {
public static void main(String[] args) {
String str1=new String("aaa");
String str2=new String("aaa");
System.out.println(str1==str2);
}
}
运行结果:
false
采用new关键字新建一个字符串对象时,JVM首先在字符串常量池中查找有没有"aaa"这个字符串对象,如果有,则不在池中再去创建"aaa"这个对象了,直接在堆中创建一个"aaa"字符串对象,然后将堆中的这个"aaa"对象的地址返回赋给引用str1,这样,str1就指向了堆中创建的这个"aaa"字符串对象;如果没有,则首先在字符串常量池池中创建一个"aaa"字符串对象,然后再在堆中创建一个"aaa"字符串对象,然后将堆中这个"aaa"字符串对象的地址返回赋给str1引用,这样,str1指向了堆中创建的这个"aaa"字符串对象。
对于上述的例子:
因为,采用new关键字创建对象时,每次new出来的都是一个新的对象,也即是说引用str1和str2指向的是两个不同的对象,因此语句
System.out.println(str1 == str2)输出:false
(3)字面量创建字符串和采用new关键字新建字符串对象比较
public class StringTest3 {
public static void main(String[] args) {
String str1="aaa";
String str2=new String("aaa");
System.out.println(str1==str2);
}
}
运行结果:
false
(4)
public class StringTest4 {
public static void main(String[] args) {
String str1="abc";
String str2="ab";
String str3=str + "c";
System.out.println(str2==str3);
}
}
运行结果:
false
字符串常量池参考blog:详解JVM常量池、Class常量池、运行时常量池、字符串常量池(心血总结)_「已注销」的博客-CSDN博客
10.2.1