一、输入、存储数据
引言
配置好Java开发环境,要编写Java程序就需要先学习Java基础语法。
Java基础语法由设计Java语言的人员规定的,在学习过程中,不需要了解为什么这样设计,应该关注每个语法格式、作用和应用场景。
学习Java语法应完成以下三个目标:
- 记住语法格式
- 掌握每个语法的作用
- 掌握应用场景
以下内容,会从三个目标进行学习。
字面量
字面量:数据在程序中的输入格式。简单来说,计算机识别整数、小数、汉字、英文等数据的输入格式,下图是数据在程序中的输入格式。
| 数据 | 生活中的写法 | 程序的输入格式 | 说明 |
|---|---|---|---|
| 整数 | 123,-456 | 123,-456 | 写法一致 |
| 小数 | 1.2,-2.1 | 1.2,-2.1 | 写法一致 |
| 字符 | a,1,字 | 'a','1','字符' | 程序中的字符必须使用单引号,只能有一个字符 |
| 字符串 | Java基础语法 | "Java基础语法" | 程序中的字符串必须使用双引号,可以没有内容 |
| 布尔值 | 真,假 | true,false | 程序中只有两个布尔值:true表示真;false表示假 |
| 空值 | 值为null | 程序中使用null表示空值 |
案例:控制台输出字面量。
//1.整数
System.out.println(123);
//2.小数
System.out.println(1.2);
//3.字符: 字符必须用单引号引起来
System.out.println('a');
System.out.println('1');
System.out.println('字');
System.out.println(' '); // 空格也算字符
//特殊字符:\t表示制表符 \n表示换行
System.out.println('\t'); // 制表符
System.out.println('\n'); // 换行符
//4.字符串
System.out.println("Java基础语法");
//5.布尔值
System.out.println(true);
System.out.println(false);
注释
注释:说明程序,方便他人阅读。
注释的语法格式
单行注释://
多行注释:/* */
文档注释:/** */
字面量的作用
方便他人阅读,明白代码的含义。
字面量的应用场景
类上使用文档注释,说明类是什么对象的抽象。
变量使用单行注释,说明变量的用途和含义
方法上使用多行文档注释,说明方法的功能。
变量
变量:内存中的一块区域,用于存储数据。可以把内存区域理解成成一个盒子,这个盒子存放一个字符串。
变量的语法格式
数据类型 变量名 = 数据;
解释语法格式
- 数据类型:盒子里只能存放这种数据类型
- 变量:单词首字母小写,从第二个单词开始首字母大写
- 数据:数据的字面量格式
变量的作用
在内存中存储数据。
当执行
String name = "张三";这句代码时,Java虚拟机在内存中申请一块区域,用于存储字符串类型的数据“张三”,这个区域名字叫name;
变量的应用场景
存储程序中会发生变化的数据。比如:银行卡余额、微信昵称。
作用域:变量的有效范围。变量定义在哪个{}中,只在哪个{}中有效。
案例:控制台输出姓名“张三”
{
String name = "张三";
System.out.println(name);
}
System.out.println(name); // name的作用域只能在{}中,超出{}无效
关键字
关键字:Java语言中具有特殊含义的单词,不能当作标识符。常见关键字含义如下:
Byte:表示字节数据类型short:表示短整数数据类型int:表示整数数据类型long:表示长整数数据类型float:表示单精度浮点数数据类型double:表示双精度浮点数数据类型char:表示字符型数据类型boolean:表示布尔(真或假) 数据类型abstract:声明抽象类或抽象方法new:表示创建一个实例public:指定类、成员、方法可以在任何地方访问。protected:指定类、成员、方法只能在类内部或子类中访问。private:指定类、成员、方法只能在类内部访问。static:用于表示成员(字段或方法)是静态的,该类不能被实例化。final:表示不可更改的变量、方法或类。对于变量,表示常量。对于方法,该方法不可被子类重写。对于类,表示不可被继承。synchronized:创建同步块,确保多个线程之间的协调执行。void:表示方法不返回任何值。class:用于声明一个类。interface:声明接口implements:实现接口。import:引入其他类或包中的成员。package:声明Java包。if:表示条件语句,用于根据条件执行不同的代码块。else:在条件语句中指定在条件不满足时执行的代码块switch:创建开关语句,根据表达式的值执行不同的代码块。case:在开关语句中匹配一个常量值。continue:用于跳过循环中的当前迭代,继续下一次迭代。break:用于跳出循环或开关语句。default:在开关语句中用于指定默认情况。for:创建for循环while:创建while循环。do:创建一个do-while循环。try:创建异常处理块。catch:捕获和处理异常。finally:指定无论是否发生异常,都会执行的代码块。throw:用于抛出异常。throws:用于声明方法可能抛出的异常。enum:声明枚举类型。extends:表示类的继承关系。super:访问父类的成员。this:引用当前对象的引用。return:从方法中返回一个值。native:标记一个方法是用本地代码(通常是C或C++)实现的。
标识符
标识符:命名变量、函数、类、模块或其他用户定义的项目的名称。比如,之前内存空间存储字符串“张三”的变量名name。
标识符的命名规则
- 由字母、数字、下划线和$组成
- 不能由数字开头
- 不能使用关键字
标识符的作用
为存储数据的内存空间取名,让该空间具有唯一的识别性。
标识符的应用场景
为类、成员、方法取名。应该遵循见名知意的命名规范。
- 类名采用大驼峰命名方式,即首字母大写
- 方法名采用小驼峰命名方式,即第一个单词首字母小写,其余单词首字母大。
休息一下吧~
二、数据和运算符
引言
前面学习了字面量、变量、知道了计算机使用变量存储数据。那么数据在计算机底层是以什么形式表示的呢?下面就学习一下数据在计算机中的底层原理。
存储原理
任何数据在计算机中都是以二进制表示的,由0和1组成。比如,整数8的二进制数是00001000。
我们已经知道了整数8的二进制数是00001000,为什么是00001000,而不是1000呢?原因是计算机中最小的存储单位是字节(Byte),一个字节占8位(bit),不足8位的数据也会用8位来存储。
随便找一张图片,图片大小也是用字节来存储。
字符的存储原理
计算机对照ASCII表,存储字符对应的二进制数值。
图片存储的存储原理
当放大图片至马赛克时,每一个小方格可以使用三原色表示,即RGB(红绿蓝),而RGB中每一种颜色可以用一个字节来存储。比如RGB(0,1,2)小方格二进制为00000000、00000001、00000010。
视频的存储原理
原理和存储图片是一样的,连续播放多张图片,一秒钟内连续播放30张以上,由于人眼感受不到画面切换的时间间隔,就认为是连续的视频了。
声音的存储原理
声音是以波的形式传播的。把声波表示在一个坐标系上,然后在坐标系上取一些点,把这些点的坐标值以二进制的形式存储到计算机中,这就是声音的存储原理。
数据类型
数据类型:规定变量存储数据的类型。
数据类型分为基本数据类型和引用数据类型。
基本数据类型有4类8种,如下图所示。
注意事项
随便写一个小数或者整数,也是有默认数据类型的。
- 比如11,它默认就为int类型;如果加上后缀L,则为long类型;
- 比如1.1,它默认为double类型;如果加上后缀F,则为float类型;
数据类型转换
自动类型转换:数据范围小的变量可以直接赋值给数据范围大的变量
自动转换原理
在较小数据类型数据空位前面补上0。
案例:byte数据类型转换为short数据类型
byte a = 20;
short b = a;
System.out.println(b);
// a = 00010100
// b = 00000000 00010100
除了byte能转成int,其他类型也可以转换,转换顺序表如下所示:
byte——>short——>int——>long——>float——>double
char——>int
注意事项
- 多种数据类型参与运算,结果会转换成最大的数据类型
- byte,short,char三种数据类型和其他类型数据运算时,都会转换为int类型再运算。
强制类型转换:强行将范围大的数据赋值给范围小的变量
强制类型转换的语法格式
目标数据类型 变量名 = (目标数据类型)被转换的数据
案例:int数据类型强制转换成byte数据类型
int a = 2; // 00000000 00000000 00000000 00000010
byte b = (byte)a;
System.out.println(b) // 00000010
强制转换的原理
只保留目标数据位数的二进制数
运算符
算数运算符:+ - * / %,其中*表示乘法,\表示除法,%表示取余。
| 符号 | 作用 | 说明 |
|---|---|---|
| + | 加 | 数学加法 |
| - | 减 | 数学减法 |
| * | 乘 | 与数学乘号×相同 |
| / | 除 | 与数学除号÷相同 |
| % | 取余 | 获得两个数据相除的余数 |
符号+除了能进行算数运算,还可以作为连接符,与字符串运算的时候用作连接符,结果是字符串。
自增自减运算符:自增++ 和 自减--
| 符号 | 作用 |
|---|---|
| 自增:++ | 放在变量前面或后面,对变量自身的值加1 |
| 自减:-- | 放在变量前面或后面,对变量自身的值减1 |
自增自减只能对变量进行操作
赋值运算符:=。将右边的值赋值给左边。
案例:将10赋值给a,将a的值赋值给b。
int a = 10; // 将10赋值给a
int b = a; // 将a的值赋值给b
此外,赋值运算符还有扩展的运算符,如下表所示。
| 符号 | 用法 | 作用 | 底层代码形式 |
|---|---|---|---|
| += | a+=b | a加b的值赋值给a | a = (a的数据类型)(a+b); |
| -= | a-=b | a减b的值赋值给a | a = (a的数据类型)(a-b); |
| *= | a*=b | a乘b的值赋值给a | a = (a的数据类型)(a*b); |
| /= | a/=b | a除b的值赋值给a | a = (a的数据类型)(a/b); |
| %= | a%=b | a除b的余数赋值给a | a = (a的数据类型)(a%b); |
关系运算符:>、>=、<、<=、==、!=。
| 符号 | 例子 | 作用 | 结果 |
|---|---|---|---|
| > | a>b | 判断a是否大于b | 成立返回true,不成立返回false |
| >= | a>=b | 判断a是否大于等于b | 成立返回true,不成立返回false |
| < | a<b | 判断a是否小于b | 成立返回true,不成立返回false |
| <= | a<=b | 判断a是否小于或者等于b | 成立返回true,不成立返回false |
| == | a==b | 判断a是否等于b | 成立返回true,不成立返回false |
| != | a!=b | 判断a是否不等于b | 成立返回true,不成立返回false |
在程序中,关系运算符常用于条件判断,根据条件判断的结果决定后续该执行哪些代码。
逻辑运算符:&、|、!、&&、||
| 符号 | 叫法 | 例子 | 运算逻辑 |
|---|---|---|---|
| & | 逻辑与 | 3>2 & 2< 3 | 全部条件为true,结果才是true;有一个为false,结果就是false |
| | | 逻辑或 | 3>2 | 2< 3 | 多个条件中,有一个为true,结果就是true |
| ! | 逻辑非 | !3>2 | 结果取反。3>2为true,结果为false |
| && | 短路与 | 3>2 && 2<3 | 判断结果与“&”一样,区别在于:左边为false,右边不执行 |
| || | 短路或 | 3>2 || 2<3 | 判断结果与“|”一样,区别在于:左边为true,右边不执行 |
三元运算符:
三元运算符的语法格式
关系表达式? 值1 : 值2
如果关系表达式的值为true,则返回值1;如果为false,则返回值2。
运算符优先级:
休息一下吧~
三、程序流程控制
引用
前面介绍了变量、数据存储原理和运算符,接下来介绍程序流程控制,结合运算符,可以做一些简单的案例。
程序流程控制分为三种:顺序结构、分支结构和循环结构。
顺序结构:从主方法开始,从上往下执行代码。
分支结构:根据条件表达式,选择性执行某些代码。Java提供了if和switch。
循环结构:根据条件表达式,循环执行某些代码。Java提供了for、while、do...while三种格式。
顺序结构
程序从主方法(main)开始,从上往下依次执行代码,直至程序运行结束。
分支结构
if分支:对条件进行判断,根据结果选择性执行代码
if语法格式1
if(条件表达式){
语句体
}
流程图如下:
案例:如果number大于2,控制台输出“111”
int number = 3;
if(number>2){
System.out.println("111");
}
if语法格式2
if(条件表达式){
语句体1
}else{
语句体2
}
流程图如下:
案例:如果number1大于number2,控制台输出“true”
int number1 = 3;
int number2 = 2;
if(number1>number2){
System.out.println("true");
}else{
System.out.println("false");
}
if语法格式3
if(条件表达式1){
语句体1
}else if(条件表达式2){
语句体2
}
...
else{
语句体n
}
流程图如下:
案例:判断分数,控制台输出对应语句。
int score = 90;
if(score<60){ // 不符合条件
System.out.println("score<60");
}else if(score<70){ // 不符合条件
System.out.println("score<70");
}else if(score<80){ // 不符合条件
System.out.println("score<80");
}else{ // 当其他条件都不符合时,执行语句体
System.out.println("score>80");
}
// 结果为System.out.println("score>80");
switch分支:通过比较值来决定执行哪条分支代码
switch分支的语法格式
switch(表达式){
case 值1:
语句1;
break;
case 值2:
语句2;
break;
case 值3;
语句3;
break;
...
case 值n-1;
break;
default:
语句n;
}
switch执行流程:
- 获取表达式的值,匹配case后的值。
- 匹配成功后,执行case对应的语句,遇到break后退出分支
- 如果全部匹配失败,则执行default的语句。
if和switch应用场景
如果判断范围,建议使用if分支结构
如果比较值,建议使用switch分支结构
注意事项:
- 表达式类型只能是byte、short、int、char
- case给出的值不允许重复,且只能是字面量
- 如果没有写break,则会出现穿透现象。
循环结构
for循环:判断循环条件是否为true,为true循环执行循环体语句,为false结束循环。
for循环语法格式
for (初始化语句; 循环条件; 迭代语句) {
循环体语句;
}
for循环执行流程:
for循环的作用
循环执行语句
for循环的应用场景
需要重复执行的语句,都可以用循环结构。
案例:求1~100之间的所有整数和
int sum = 0;
for(int i = 1;i<100;i++){
sum+=i;
}
System.out.println(sum) // 5050
/* 分析执行流程
i=1 sum=0+1 sum=1
i=2 sum=1+2 sum=3
i=3 sum=3+3 sum=6
...
i=100 sum=4950 sum=5050 */
while循环:判断循环条件是否为true,为true循环执行循环体语句,为false结束循环。
while循环的语法格式:
while (循环条件) {
循环体语句;
迭代条件;
}
案例:求1~100之间的所有整数和
int num = 1;
int sum = 0;
while(num<=100){
sum+=num++;
}
/* 分析执行流程
num=1 sum=0+1 sum=1
num=2 sum=1+2 sum=3
num=3 sum=3+3 sum=6
...
num=100 sum=4950+100 sum=5050 */
do...while循环:先执行循环体语句,再判断循环条件是否为true,为true循环执行循环体语句,为false结束循环。
do...while循环的语法格式
do{
循环体语句;
迭代条件;
}while (循环条件);
案例:求1~100之间的所有整数和
int num = 1;
int sum = 0;
do{
sum+=num++;
}while(num<=100);
/* 分析执行流程
num=1 sum=0+1 sum=1
num=2 sum=1+2 sum=3
num=3 sum=3+3 sum=6
...
num=100 sum=4950+100 sum=5050 */
for、while、do...while应用场景
未知循环次数情况下,推荐使用while循环
已知循环次数情况下,推荐使用for循环
需要先执行某些语句,才能判断循环条件,推荐使用do...while循环。
循环嵌套
循环嵌套:循环中嵌套一个循环。
循环嵌套的执行流程: 外循环一次,内循环全部次数
循环嵌套的应用场景
多维数据处理、搜索和遍历等等
案例:在控制台使用 * 打印出4行5列的矩形
// 外层控制*的行数
for (int i = 1; i <= 4; i++) {
// 内层控制*的个数
for (int j = 1; j <= 5; j++) {
System.out.print("*");
}
System.out.println();
}
/*
*****
*****
*****
*****
*/
跳转语句
break:跳出并结束当前的循环
continue:结束本次循环,进入下一次循环
break 、continue的应用场景
常用于控制循环流程
休息一下吧~
四、数组
数组:存储相同数据类型的有序容器。
静态初始化
静态初始化标准格式
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};
静态初始化简化格式
数据类型[] 变量名 = {元素1,元素2,元素3};
存储原理
数组是一个引用数据类型,创建一个数组时,会在堆内存分配一块连续的内存空间,存储数组的所有元素,数组名存储内存空间的起始地址,然后通过索引获取对应的元素。
案例:数组初始化格式
// 标准格式:
int[] ages = new int[]{1, 2, 3};
// 简化格式:
int[] ages = {1, 2, 3};
访问数组
访问数组格式
数组名[索引]
案例:控制台输出ages数组的第一个元素
int[] ages = {1,2,3};
System.out.println(ages[0]);
遍历数组
遍历数组格式
for(int i =0;i<数组.length;i++){
数组[i]
}
案例:控制台打印数组的元素
int[] ages = {3,4,5};
for(int i=0;i<ages.length;i++){
System.out.println(ages[i]);
}
动态初始化
动态初始化标准格式
数据类型[] 变量名 = new 数据类型[数组元素的长度];
存储原理
和静态初始化类似,区别在于索引指向的元素是数据类型的默认值。
数据类型的默认值如下表所示
| 数据类型 | 具体 | 默认值 |
|---|---|---|
| 基本类型 | byte、short、char、int、long | 0 |
| 基本类型 | float、double | 0.0 |
| 基本类型 | boolean | false |
| 引用类型 | 类、接口、数组、字符串 | null |
数组的作用
存储大量相同数据类型的数据
休息一下吧~
五、方法
方法:方法是一种语法结构,把一段代码封装成一个功能,便于重复调用。
方法语法格式
修饰符 返回值类型 方法名(形参列表){
方法体;
return 返回值;
}
案例:张三、李四都需要求和,做着相同求和的事情,用一个方法封装求和功能。
public class MethodDemo {
public static void main(String[] args) {
// 1、张三
int sum1 = getSum(10, 20);
System.out.println("和是:" + sum1);
// 2、李四
int sum2 = getSum(30, 20);
System.out.println("和是:" + sum2);
}
public int getSum(int num1,int num2){
int sum = num1+num2;
return sum;
}
}
方法执行流程
- 通过方法名找到对应方法
- 将实参传入方法形参
- 把返回值传递给调用处
方法设计原则
- 如果方法不需要返回数据,返回值类型必须申明成void, 此时方法内部不可以使用return返回数据。
- 方法如果不需要接收外部传递进来的数据,则不需要定义形参,且调用方法时也不可以传数据给方法。
方法执行原理
调用方法时,会把方法压入虚拟机桟内存中,调用完毕后自动弹桟。
用前面张三、李四求和案例进行说明:
- MethodDemo.java通过Java编译器编译成字节码文件。
- Java虚拟机将字节码文件的所有方法存入方法区,在桟内存创建一个桟帧存放主方法。
- 执行主方法,当执行getSum()方法时,会创建一个桟帧存放getSum()方法。
- 执行getSum()方法时,会将实参传递给方法的形参,方法将返回值传递给方法调用处,执行完毕后,将getSum()进行弹桟。
- 执行
System.out.println("和是:" + sum1);方法时,会创建桟帧存入println("和是:" + sum1)方法。 - 执行println("和是:" + sum1)方法,将字符串内容打印到控制台上。执行完毕后,将println("和是:" + sum1)方法进行弹桟。
- 主方法执行完毕后进行弹桟。
方法的作用
提高了代码的复用性,封装功能的实现细节,外部调用时只需要知道方法的输入参数、功能和返回结果。
方法重载
方法重载:一个类中有多个方法名相同、参数不同的方法。
方法重载的作用
多个相同功能的方法,可以接收不同的参数,避免方法名冲突,简化API设计。
方法重载的应用场景
为一类业务,提供多种解决方案。
方法重写
方法重写:子类继承父类的方法,在子类重新定义与父类相同返回类型、方法名和参数的方法。重写的方法在子类会覆盖与父类相同的方法。
方法重写的作用
子类与父类实现方法的方式不同,提高可扩展性。
方法重写的应用场景
设计框架和类库。
总结
JavaSE基础语法的知识点多且杂,完全理解需要进行大量的编程训练,下图是梳理知识点的思维导图,希望对您有帮助。
如果对您有帮助,请给我点个赞,您的鼓励就是我最大的动力。如果发现文章中存在任何错误,请不吝指出,我会及时改正。