语言:人与人交流沟通的表达方式
计算机语言:人与计算机之间进行信息交流沟通的一种特殊语言
编程语言的发展历程:机器语言、汇编语言、高级语言
☀️ Java 语言的历史
Java语言是美国 Sun 公司(Stanford University Network)在 1995 年推出的计算机 高级编程语言(更接近人类语言) ,2009年,被Oracle(甲骨文)公司收购
Java之父:詹姆斯·高斯林(James Gosling)
☀️ Java 的特点与优势
☀️ Java 语言的版本
✨ 拓展
- 网页:通过浏览器将数据展示在用户面前,跟后台服务器没有交互(是静态数据)
- 网站:通过跟后台服务器的交互,将查询到的真实数据再通过网页展示出来
- 网站=网页+后台服务器
JVM(Java Virtual Machine ):Java 虚拟机,简称 JVM,是运行所有Java程序的假想计算机,是真正运行Java程序的地方,是Java 最具吸引力的特性之一。我们编写的Java代码,都运行在 JVM 之上
JRE (Java Runtime Environment) :是Java程序的运行环境,包含 JVM 和运行时所需要的Java核心类库 。
JDK (Java Development Kit):是 Java 程序开发工具包,内部包含了代码的编译工具和运行工具。
结论:
- 三者关系: JDK > JRE > JVM
- 我们现阶段只要安装了JDK即可拥有java程序开发和运行需要的全部环境
- 如果是在企业的部署环境下,其实只需要安装JRE就可以运行编译好的Java程序了
❗️注意:
- 在 Java 开发工具包(JDK)中,有一些版本是长期支持(LTS)版本。LTS版本指的是在发布后会提供更长时间的技术支持和安全更新的版本
- JDK8 (2014年3月)
- JDK11 (2018年9月)
- JDK17 (2021年9月)
- JDK21 (预计2023年9月发布)
- JDK的下载需访问 Oracle官网,安装成功之后通过在命令终端输入
javac -version
、java -version
查看版本号验证
- 目前较新的JDK安装时会自动配置
java
、javac
命令的路径到Path
环境变量中C:\Program Files\Common Files\Oracle\Java\javapath
,所以java
、javac
命令可以直接使用,但是以前下载的老版本JDK是没有自动配置的,此时需要我们手动配置Path
环境变量
- 新建系统变量
JAVA_HOME
,变量值设置为JDK的安装路径,如:D:\StudyTools\Java\jdk-17
- 编辑
Path
环境变量,新建
输入%JAVA_HOME%\bin
☀️ Java 语言 的 跨平台 特性:一次编译,处处可用。
任何软件的运行,都必须要运行在操作系统之上,而我们用Java 编写的软件可以运行在任何的操作系统上,该特性是由 JVM 实现的,我们编写的程序运行在 JVM 上,而 JVM 运行在操作系统上。
如上图所示,在不同的操作系统中,都安装一个与操作系统对应的Java虚拟机即可。
❗️注意:
- 跨平台中的“平台”是指“操作系统”,Java语言可以在任意操作系统上运行,是允许跨平台的,而Java的虚拟机本身不具备跨平台功能的,
Java 程序的开发,需要三个步骤:编写代码、编译代码、运行代码
1️⃣ 编写(需要使用JRE中Java已经编写好的代码)
编写Java源文件HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
main
方法:称为主方法。写法是 固定格式 不可以更改。main
方法是程序的入口点或起始点,无论我们编写多少代码,JVM 在运行的时候,都会从 main
方法这里开始执行。
❗️注意:
- 因为有
public
,所以文件名必须是HelloWorld
,保证文件名(首字母大写,满足驼峰式)和类的名字是一致的,注意大小写,若没有public
,则不限制类名必须与文件名一致- 这个文件后缀名为
.java
,属于源文件,是程序员编写的,JVM 是看不懂的,也就不能运行,因此我们必须将编写好的 Java 源文件编译成 JVM 可以看懂的.class
文件,即字节码文件,该文件可以被 JVM 直接识别并执行。
2️⃣ 编译(需要使用JDK中的编译工具)
Java源文件的编译工具 javac.exe
在DOS命令行中,进入Java源文件的目录,使用javac
命令进行编译
javac Java源文件名.后缀名
即
javac HelloWorld.java
编译成功后,命令行没有任何提示。打开文件所在目录,发现产生了一个新的文件 HelloWorld.class
,该文件就是编译后的文件,是Java的可运行文件,称为 字节码文件 ,有了字节码文件,就可以运行程序了
3️⃣ 运行(需要使用JDK中的运行工具,代码需要运行在JRE中的JVM中)
Java字节码文件的运行工具 java.exe
在DOS命令行中,进入Java源文件的目录,使用 java
命令进行运行
java 类名字
即
java HelloWorld
❗️注意
- 运行时,字节码文件名
HelloWorld
不要加后缀- 从JDK11开始,支持直接运行 Java 源文件,即
java HelloWorld.java
,期间也不会产生字节码文件java
和javac
命令都存放在 JDK 安装目录下的bin
目录下
✨ 拓展:常用DOS命令
❗️注意:
- 终端退出 python 环境的命令是
exit()
注释,就是对代码的解释和说明
其目的是让人们能够更加轻松地了解代码。为代码添加注释,是十分必要的,它不影响程序的编译和运行
Java中的注释分类:
//
开头 以换行结束 /*
开头 以*/
结束/**
开始,以*/
结束,一般用在类和方法上字面量,也叫常量,是指在Java程序中固定不变的数据
❗️注意:
- 空常量不能用来打印输出
- 字符(必须单引号)里面必须有内容,字符串(必须双引号)里面可以没有内容
- 打印布尔值输出就是本身,而不是0或1
变量,常量是固定不变的数据,那么在程序中可以变化的量称为变量,变量就是用来存储一个数据的内存区域,且里面存储的数据是可以变化的
Java中要求一个变量每次只能保存一个数据,必须要明确保存的数据类型
定义变量:
// 方法一:
数据类型 变量名 = 数据值;// 在创建一个变量的同时,立刻放入指定的数据值
// 方法二:
数据类型 变量名称; // 创建了一个变量
变量名称 = 数据值; // 赋值,将右边的数据值,赋值交给左边的变量
❗️注意:
- 变量赋值:定义的变量,不赋值不能使用(变量定义的时候可以没有初始值,使用的时候必须给 初始值)
- 前面没有数据类型时不属于变量的定义,属于变量的使用
- 变量名称:在同一个大括号范围内,变量的名字不可以相同
- 变量的作用域:只在变量所在的大括号内有效,大括号中的代码一旦执行完毕,其内部所定义的变量就会从内存中消失
- 如果使用byte或者short类型的变量,那么要注意右侧的数据值不能超过左侧类型的范围
可以通过一个语句来创建多个变量(需要通过逗号分割),但是一般情况不推荐这么写
// 同时创建了三个全都是int类型的变量
int a, b, c;
// 各自分别赋值
a = 10;
b = 20;
c = 30;
// 同时创建三个int变量,并且同时各自赋值
int x = 100, y = 200, z = 300;
计算机底层都是一些数字电路(理解成开关),用开表示0、关表示1,这些01的形式就是二进制。
数据在计算机底层都是采用二进制存储的。
那二进制是如何表示数据的呢?
在计算机中认为一个开关表示的0或1称为1位(b),每8位称为一个字节(B), 所以1B=8b
。
字节 是计算机中数据的最小单位
Java的数据类型分为两大类:
四类八种基本数据类型:
❗️注意:
- Java中的 默认 类型:整数类型是
int
、浮点类型是double
long
类型:建议数据后加L
表示,float
类型:建议数据后加F
表示,但是打印输出时并不会有L
或F
e+38
表示是乘以10的38次方,同样,e-45
表示乘以10的负45次方。
✨ 拓展:ASCII编码表
在计算机的内部都是二进制的0、1数据,将所有的英文字母,数字,符号都和十进制进行了对应,计算机可以直接识别人类文字
1️⃣ 自动类型转换(隐式转换)
自动转换:将取值范围小的类型自动提升为取值范围大的类型。
❗️注意:
- 小的数据类型和大的数据类型运算,小的会提升为大的之后再进行计算,表达式的最终结果类型由表达式中的最高类型决定
byte/short/char
这三种类型在运算的时候,不管是否有更高的数据类型,都会被首先提升成为int
类型,然后再计算float
为4字节,但其范围比8字节的long
要大
举个栗子:
public static void main(String[] args) {
byte b1 = 1;
byte b2 = 2;
// 正确语句
byte b3 = 1 + 2;
// 错误语句
byte b4 = b1 + b2;
// 解决办法
// byte b4 = byte(b1+b2)
System.out.println(b3); // 3
System.out.println(b4);
}
分析:
b3 = 1 + 2
,1
和2
是常量,为固定不变的数据。Java存在 常量优化机制,在编译的时候就会让1
和2
相加,然后会自动判断1+2
的结果没有超过byte
类型的取值范围,可以赋值给变量b3
,因此b3=1 + 2
是正确的。 反之,b4 = b1 + b2
,b1
和b2
是byte
类型,计算时会直接提升为int
,因此会将结果以int
类型进行处理,所以int
类型不能赋值给byte
类型,因此编译失败。
2️⃣ 强制类型转换(显式转换)
强制转换:将取值范围大的类型强制转换成取值范围小的类型
比较而言,自动转换是Java自动执行的,而强制转换需要我们自己手动执行
转换格式:
数据类型 变量名 = (数据类型)被转数据值;
// double类型数据强制转成int类型,直接去掉小数点后面的数字。
int i = (int)1.9; // i的值为1
❗️注意:
- 浮点转成整数,直接去掉小数点后面的数字,可能造成数据损失精度。
int
强制转成short
砍掉2个字节,可能造成数据丢失boolean
类型不能发生数据类型转换
关键字是指在程序中,Java已经定义好的单词,具有特殊含义。
HelloWorld案例中,出现的关键字有 public
、 class
、 static
、 void
等,这些单词已经被 Java 定义好,全部都是小写字母,notepad++中颜色特殊。
❗️ 注意:
- 关键字很多,我们不用刻意去记
- 我们不能用关键字作为类名或者变量名称,否则报错
标识符:是指在程序中,我们自己定义内容。比如类的名字、方法的名字和变量的名字等等,都是标识符。
HelloWorld案例中,出现的标识符有类名字 HelloWorld
命名规则: 硬性要求
英文字母26个
(区分大小写) 、 0-9数字
、 $
(美元符号) 和 _
(下划线)命名规范: 软性建议
❗️注意:
- Java中,整数使用以上运算符,无论怎么计算,也不会得到小数,要想得到小数,必须有浮点数参与运算(特别是
/
,在Java中两个整数相除结果还是整数,因为最高类型是整数)- 变量在独立运算时,
前++
和后++
没有区别,和其他变量放在一起,前++
和后++
就产生了不同,前++
先自增再拿变量进行操作,后++
先拿变量进行操作再自增。前--
和后--
同理。- 一旦运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。
- 只有对于整数的除法来说,取模运算符才有余数的意义
- 对于字符串String(首字母大写,并不是关键字)来说,
+
代表字符串连接操作。任何数据类型和字符串进行连接的时候,结果都会变成字符串
public static void main(String[] args) {
int i = 1234;
System.out.println(i/1000*1000); // 1000
System.out.println(10/3); // 3
System.out.println(10.0/3); //3.33333333……
// 字符串“+”操作,此时“+”为字符串连接符,而不是算术运算【能算则算,不能算就在一起】
String str = "Java";
System.out.println(str + 20 + 30); // Java2030
System.out.println(str + (20 + 30)); // Java50
System.out.println(20 + 30 + str); // 50Java
System.out.println("5+5="+5+5);//输出5+5=55
// 字符“+”操作
int a = 1;
char b = 'a';
System.out.println(a+b); // 98
// ++操作(不能对常量进行操作)
int c = 123;
System.out.println(c++); //123,先把c的值取出来进行打印操作后再加1
System.out.println(c); //124
}
举个栗子: 数值拆分案例
键盘录入一个三位数,将其拆分为个位,十位,百位,打印在控制台
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
// 1:使用Scanner键盘录入一个三位数
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个三位数");
int num = sc.nextInt();
// 2:个位的计算:数值 % 10
int ge = num % 10;
// 3:十位的计算:数值 / 10 % 10
int shi = num / 10 % 10;
// 4:百位的计算:数值 / 100
int bai = num / 100;
// 5:将个位, 十位, 百位拼接上正确的字符串, 打印即可
System.out.println("整数"+num+"个位为:" + ge);
System.out.println("整数"+num+"十位为:" + shi);
System.out.println("整数"+num+"百位为:" + bai);
}
}
✨ 拓展:数值拆分公式总结
- 个位:数值%10
- 十位:数值/10%10
- 百位:数值/10/10%10
- 千位:数值/10/10/10%10
- ……
✨ 拓展:
- 复合赋值运算符底层会自带强制类型转换功能
public static void main(String[] args) {
short s = 1;
// int + int = int,将int赋值给short需要强转,故该程序会报错
s = s + 1; // 会报错,解决办法: 改为:s = (short)(s+1);
System.out.println(s);
short ss = 1;
// ss = (short)(ss+1) 复合赋值运算符底层会自带强转功能
ss += 1;
System.out.println(ss); // 2
}
分析:
s += 1
逻辑上看作是s = s + 1
,计算结果被提升为int
类型,再向short
类型赋值时发生错误,因为不能将取值范围 大的类型赋值到取值范围小的类型。但是,s=s+1
进行两次运算 ,+=
是一个运算符,只运算一次,并带有强制转换的特点, 也就是说s += 1
就是s = (short)(s + 1)
,因此程序没有问题编译通过,运行结果是2
比较运算符,是两个数据之间进行比较的运算,运算结果都是布尔值 true
或者 false
逻辑运算符,是用来连接两个布尔类型结果的运算符,运算结果都是布尔值 true
或者 false
&
,无论左边真假,右边都要执行。|
,无论左边真假,右边都要执行。短路与&&
,如果左边为真,右边执行;如果左边为假,右边不执行。(一假即假)
短路或||
,如果左边为假,右边执行;如果左边为真,右边不执行。(一真即真)
int x = 3;
int y = 4;
System.out.println((x++ > 4) & (y++ > 5)); // 两个表达都会运算
System.out.println(x); // 4
System.out.println(y); // 5
System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为false,右边不参与运算
System.out.println(x); // 4
System.out.println(y); // 4
❗️注意:
- 在Java中,如果进行多次判断,不能连着写,在Python中可以
System.out.println(1 < x < 3); // 错误写法!编译报错!不能连着写。
三元运算符格式:
数据类型 变量名 = 布尔类型表达式?表达式1:表达式2
三元运算符计算方式:
❗️注意:
- 必须同时保证表达式1和表达式2都符合左侧数据类型的要求。
- 三元运算符的结果必须被使用
举个栗子:三元运算符案例
一座寺庙里住着三个和尚,已知他们的身高分别为150cm、210cm、165cm,请用程序实现获取这三个和尚的最高身高。
public static void main(String[] args) {
//1:定义三个变量用于保存和尚的身高,单位为cm,这里仅仅体现数值即可。
int a = 150;
int b = 210;
int c = 165;
//2:用三元运算符获取前两个和尚的较高身高值,并用临时身高变量保存起来。
int temp = a > b ? a : b;
//3:用三元运算符获取临时身高值和第三个和尚身高较高值,并用最大身高变量保存。
int result = temp > c ? temp : c;
//4:输出结果
System.out.println("maxHeight:" + result);
// int result = temp > c ? temp : c;
// temp = a > b ? a : b 带入上式得:
// int result = a > b ? a : b > c ? a > b ? a : b : c;// 可行,但不推荐,不易阅读
}