java小白第一天
写在前面
本文是边看黑马b站视频边写的一片笔记, 文中大多图片都来自黑马视频. 旨在巩固学习以及方便后续查阅和供广大朋友们学习, 感谢黑马视频分享
一个Java程序的诞生步骤
- 编写代码,得到HelloWorld.java文件
public class HelloWorld{
public static void main(String[] args){
System.out.println("hello world");
}
}
note:文件名与代码中的类名完全一致
- 编译 javac.exe, 得到 .class 文件
A:\code\java_base>javac HelloWorld.java
- 运行 java.exe
A:\code\java_base>java HelloWorld
hello world
- jdk与jre
一些小概念
开发工具
- jdk17
- idea
idea
idea项目结构介绍
- 项目 empty project
- 模块
- 包
- 类
- 包
- 模块
一开始是创建 empty project
创建java模块
关键字
被java赋予了特定涵义的英文单词,都是小写,有特殊颜色标记
标识符
标识符即用户自己起的名字
硬性要求
- 由数字、字母、下划线、美元符组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
软性建议
小驼峰(第一个单词首字母小写,其他单词首字母大写):方法,变量
大驼峰(每个单词的首字母都大写):类名
见名知义
字面量
字面量:数据在程序中的书写格式
特殊字符字面量
- \t 制表符
在打印的时候,把前面的字符串的长度补齐到8,或者8的整数倍,最少补一个字符,最多补8个字符
**note:**使用时,单引号、双引号都可以
变量
定义格式:数据类型 变量名 = 数据值;
note:
- 只能存储一个值
- 变量名不允许重复定义
- 一条语句可以定义多个变量
int a = 10, b = 20, c = 30;
- 变量在使用前一定要赋值
- 注意变量的作用域
计算机中的数据存储
计算机中的数据类型
文本
图片
声音
计算机中各种进制
进制转换
任意进制转换为十进制
十进制转换为其他进制
美国信息交换标准码表
American Standard Code for Information Intercharge
文本数据–以各种码表对应二进制数据存储
图片数据
黑白图
灰度图
彩色图
计算机中的光学三原色:红绿蓝
声音数据
数据类型
分为基本数据类型和引用数据类型
基本数据类型
基本类型数据–四类八种
示例
上述两张图片的代码运行结果
引用数据类型
定义 存储的地址的数据类型是引用数据类型
note
- 基本数据类型变量存储的是真实的数据
- 基本数据类型的数据值存储在自己的内存空间中
- 基本数据类型赋值给其他变量时,赋的是真实的值
- 引用数据类型变量存储的是堆内存的地址值
- 引用数据类型的数据值存储在其他空间中,自己空间中存储的是地址值
- 引用数据类型赋值给其他变量时,赋的是地址值
键盘录入–Scanner
- 导包 import java.util.Scanner;
- 创建对象 Scanner sc = new Scanner(System.in);
- 使用–接收数据 int i = sc.nextInt();
运算符
运算符: 对字面量或者变量进行操作的符号
表达式: 用运算符把字面量或者变量连接起来,符合java语法的式子就可以称之为表达式
算术运算符
note:
- 代码中,有小数参与的运算结果可能会不准确
- .整数相除结果仍然是整数
- 小数相除结果是小数, 结果可能不精确
高级运算:
01 数值
数字进行运算时,数据类型会自动转换成一致的
隐式转换:把取值范围小的数值转换为取值范围大的数值(自动转换)
隐式转换的两种提升规则:
- 小转大,再计算
- byte short char 三种类型的数据在运算的时候,都会直接提升为int,然后再进行运算
public class HelloWorld {
public static void main(String[] args) {
System.out.println("hello world");
char a = 'a';
char b = 'b';
System.out.println(a+b); // 195
System.out.println(a-b); // -1
System.out.println(a/b); // 0
System.out.println(a*b); // 9506
System.out.println(a%b); // 97
}
}
一些案例
note: byte 与 short 运算时都是直接提升为int, 然后进行运算
强制转换:
当把一个取值范围大的类型的数据赋值给取值范围小的类型的变量时,是不允许直接赋值的,需要使用强制转换
强制转换格式: 目标数据类型 变量名 = (目标数据类型) 被转换的数据;
**note: ** 强制转换可能丢失数据精度
02 字符串
字符串的 ‘+’ 操作(拼接)
此时, ‘+’ 是字符串连接符,将前后的数据(这里的数据只需其中有一个是字符串即可)进行拼接, 产生一个新的字符串
1 + 99 + "aaa" // 100aaa
"aaa" + true // aaatrue
'中' + "aaa" + true // 中aaatrue
**note: ** 表达式运算时,从左到右进行
03 字符
字符通过ASCII码表查询到对应数字进行计算
自增自减运算符
赋值运算符
**note: ** 扩展的赋值运算符隐含了强制类型转换,示例图如下
关系运算符
逻辑运算符
短路运算符
逻辑与当左边为假时,右边不执行
逻辑或当左边为真时,右边不执行
提高效率
三元运算符
**运算符格式: ** 关系表达式 ? 表达式1 : 表达式2;
**note: ** 需要说明的是, 三元运算符的结果必须被使用, 可以赋值给变量, 或者打印输出
原码 反码 补码
原码: 十进制数据的二进制表现形式, 最左边是符号位, 0为正, 1为负
反码: 正数的反码是其本身, 负数的反码是符号位保持不变, 其余位取反
补码: 正数的补码是其本身, 负数的补码是在其反码的基础上加一
8个位一个字节
一个字节最大数 127
一个字节最小数 -128
利用原码对正数计算没有问题, 但对负数计算正好方向相反, 所以利用负数的反码进行计算
但是, 利用反码计算负数时, 由于+0 和 -0 的反码不一样, 所以会在从负数跨越到正数时出现数值为1的误差
因此, 计算机中数据的存储和计算使用补码, 即在反码上+1, 使得+0和-0的反码一致
其他运算符
note:
- 左移运算符, 高位即符号位保持一致
示例
流程控制语句
分支结构
if 语句
if 语句格式:
if (关系表达式){ // 语句体 }
if (关系表达式){ // 语句体1 } else { // 语句体2 }
if (关系表达式1){
// 语句体1
} else if (关系表达式2){
// 语句体2
} else if (关系表达式3){
// 语句体3
} ...
else {
// 语句体n+1
}
note:
- 在语句体中只有一句代码,格式中的大括号可以不写
- 小知识
int = 10;
是两句代码 - 格式2是二选一
switch 语句
switch 语句格式:
switch (表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
note:
- default可以省略, 当所有 case 都不匹配时, switch 语句没有反应
- default位置不一定要在最下面, 但习惯在最下面
- case 穿透, 当某个case匹配成功时, 若没有break, 程序会继续执行后面的case以及default, 直到遇到break语句,或者到达switch语句末尾
- switch 新特性(jdk12):
- 省略了break, 使用箭头形式书写, 没有case穿透现象
- 大括号只有一句代码可以省略
- 可以用一个变量接收switch结果
后面讲
循环语句
for 循环格式:
for (初始化语句; 条件判断语句; 条件控制语句){
// 循环体语句
}
while 循环格式:
初始化语句;
while(条件判断语句){
// 循环体语句
条件控制语句
}
do … while 格式
初始化语句;
do{
循环体语句
条件控制语句
}while(条件判断语句);
note: 先执行后判断, 即该循环语句即使条件不满足, 也会执行一次循环体
无限循环
跳过与终止
continue : 一般与if判断语句结合,跳过本次循环
break : 跳出循环语句
数组
概念
定义: 数据就是一个容器, 存储的元素具有相同的数据类型
数组创建格式:
数据类型[] 数组名
int[] array
数据类型 数组名[]
int array[]
数组的初始化
数组的静态初始化
初始化: 在内存中为数组容器开辟空间,并给数组赋值
完整格式 数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};
简化格式
数据类型[] 数组名 = {元素1,元素2,元素3...};
note:
- 数组一旦创建,长度不可变
数组的访问
-
数组名记录数组在内存中的地址
- 数组地址值的格式含义:
public static void main(String[] args) { int [] arr1 = {1,2,3}; System.out.println(arr1); // [I@1b6d3586 } [I@1b6d3586 [ : 表示该变量是一个数组 I : 表示数组的元素是 int @:表示一个间隔符号 (固定格式) 1b6d3586:是数组在内存中的地址
-
数组元素访问
- 访问格式
数组名[索引]
- 访问格式
-
数组遍历
- 便捷形式:
array.fori
, 效果如下public static void main(String[] args) { int [] arr1 = {1,2,3}; System.out.println(arr1); for (int i = 0; i < arr1.length; i++) { System.out.println(arr1[i]); } }
- 便捷形式:
数组的动态初始化
动态初始化: 初始化时只指定数组的长度,由系统为数组分配初始值
动态初始化数组格式:数据类型[] array = new 数据类型[数组长度];
数组默认初始值
数据类型 | 初始值 |
---|---|
整数类型 | 0 |
小数类型 | 0.0 |
字符类型 | ‘/u0000’ 空格 |
布尔类型 | false |
引用类型 | null |
数组内存图
java程序的jvm运行的内存占用详情图
这里为了方便描述,仍然给出了方法区
方法在栈中,new 出来的在堆中
示例1
示例2 数组内存图
示例3
note: 引用类型的数据,会在堆中开辟一片内存空间,对应的变量名存储堆中对应内存空间的地址,因此当将该变量赋值给另一个变量时,此时,这两个变量指向的内存地址是同一个地址,通过两者中的任一个变量修改该内存地址中存放的内容,另一个变量访问时,访问到的也是修改之后的内容
数组常见问题
- 数组索引越界问题
方法
- 方法是程序中最小的执行单元
- 提高代码的复用性,可维护性
什么是方法
- 方法需要先定义再调用
- 定义在main方法外面,类里面
方法的定义格式
修饰符 返回值类型 方法名 (参数列表) {
// 方法体
return 返回值;
}
note:
1. 参数列表
+ 多个参数用逗号隔开
+ 参数格式: 数据类型 变量名
+ 调用时,实参和形参一一对应(数量,类型)
2. 带返回值方法的调用
+ 直接调用 `方法名(实参);`
+ 赋值调用 `数据类型 变量名 = 方法名(实参);`
修饰符 | 含义 | 备注 |
---|---|---|
public static | 公开静态 | 类可直接调用,同一类中其他方法可调用 |
方法的重载
定义 – 同类同名不同参
- 在同一个类中,定义多个同名的方法,这些同名的方法具有同种功能
- 方法的重载只与参数列表有关,与返回值无关
- 即,同一个类中,方法名相同,参数不同(参数个数,参数类型,参数顺序),不看返回值与修饰符的一系列同名方法就是方法重载
- java虚拟机通过传入实参的不同调用同名的重载方法
示例
方法的内存
方法值的传递
- 传递基本数据类型时, 传递的是真实的数据,形参的改变, 不影响实际参数的值
- 传递引用数据类型时, 传递的是变量存储的地址值, ****
public class HelloWorld {
public static void main(String[] args) {
int [] arr1 = {1,2,3};
System.out.println(arr1[0]); // 1
isArrayChannge(arr1);
System.out.println(arr1[0]); // 30
}
// 方法值的传递--引用数据类型的传递
public static void isArrayChannge(int[] arr){
arr[0] = 30;
}
}