java学习
简介
Java是什么
人与人交流沟通的表达方式通过语言,那我们与计算机进行信息交流沟通通过什么语言呢?
Java是一门优秀的计算机语言之一,还有其他优秀的计算机语言如:C
,C++
,Go
,Python
等等。
Java之父:詹姆斯·高斯林(James Gosling)
java能做什么
java主要做企业服务器端软件的开发
,占据90%以上的市场份额
服务端开发主要有以下几点:
- 数据响应
- 数据管理
- 业务分析
- 推荐算法
- 服务降级
- 集群脑裂
- 安全认证
- 权限管理
- 性能优化
- 事务管理
等等。
java平台分类
javaSE是java的核心和基础,是其他两个平台的基础,也可以开发桌面应用程序
javaEE,企业服务端开发的一套解决方案,可用于服务端应用开发
javaME,针对移动应用的解决方案,可开发小型或移动设备中的应用
jdk版本
我们必须安装JDK
才能使用java,所谓的JDK(java development kit)
就是java开发者工具包
jdk的重要历史版本如下:
- 2014年
JDK8(LTS)
- 2018年9月
JDK11(LTS)
- 2021年9月
JDK17(LTS)
- 2023年9月
JDK21(LTS)
注意:所谓的LTS
就是长期支持版本(Long term support)
大部分企业为了系统的稳定,大部分选择的版本是JDK8
,现在很多企业现在逐渐使用JDK11
来进行开发了
jdk中的java与javac
java是执行工具,javac是编译工具
我们写的java程序是高级语言,计算机底层硬件是无法识别这些高级语言的,必须通过javac编译工具进行翻译,然后再通过java执行工具执行才能驱动机器干活
jdk组成
jdk主要由三部分构成:JVM
,核心类库
,开发工具
JVM:java虚拟机,真正运行java程序的地方,java是一门跨平台的语言,究其根本是java为每个平台构建了对应的JVM虚拟机
核心类库:java自己写好的程序,方便程序员调用的
其中JVM
与核心类库
构成了java的运行环境(JRE)
基础语法
注释
注释是写在程序中,对代码进行解释说明的文字,主要为了方便自己和他人查看,以便理解程序的
分类
单行注释
|
|
多行注释
|
|
文档注释
|
|
特点
注释不影响程序的执行(注释只作用在写代码阶段,编译后的class文件中已经没有注释了,所以注释不会影响程序的执行)
文档
我们可以根据文档注释来生成api文档,方便我们查阅
|
|
这样就会根据HelloWorld中的文档注释将文档生成到指定目录中去了
数据类型
基本数据类型
基本数据类型分为4大类8种
1字节=8位 所以1byte占用数据类型最大值为1111 1111 = 256
整型
数据类型 | 内存占用(字节) | 数据范围 |
---|---|---|
byte | 1 | -128~127 |
short | 2 | |
int(默认) | 4 | 大约21亿多 |
long | 8 | 19位数 |
|
|
浮点型
数据类型 | 内存占用(字节) | 数据范围 |
---|---|---|
float | 4 | |
double(默认) | 8 |
|
|
字符型
数据类型 | 内存占用(字节) | 数据范围 |
---|---|---|
char | 2 | 0~65535 |
布尔型
数据类型 | 内存占用(字节) | 数据范围 |
---|---|---|
boolean | 1 | true,false |
类型转换
自动类型转换
类型范围小的变量,可以直接赋值给类型范围大的变量
|
|
表达式的自动类型转换
在表达式中,小范围类型的变量,会自动转换成表达式中较大范围的类型,在参与运算
注意:
- 表达式的最终结果类型由表达式中的
最高类型决定
- 在表达式中,byte、short、char是
直接转换成int
类型参与运算的
|
|
强制类型转换
大范围类型的变量 => 小范围类型的变量
|
|
浮点型强制转换成整型,直接丢掉小数部分,保留整数部分返回
引用数据类型
变量
定义
就是给程序要处理的数据起一个名字,方便我们后期处理这个数据
声明
变量定义格式如下:
|
|
注意
- 变量要先声明才能使用
- 变量是什么类型,就必须装载什么类型的数据
- 变量是从定义开始到“}”截止的范围内有效
- 同一范围内,变量的名称不能一样
- 变量定义的时候可以不赋初始值,但在使用时,变量里必须有值
- 变量存储在内存中的一块区域
关键字
java语言自己使用到的一些词汇,有特殊作用的,我们称之为关键字。
常见关键字如下:
public
,class
,int
,double
…..
标识符
标识符就是名字
基本要求
一般由数字、字母、下划线(_)和$符组成
强制要求
不能以数字开头,不能是关键字,不能包含一些特殊字符(&,%,#….)
建议
变量名:建议首字母小写,如:studyNumber
类名:建议首字母大写,如:HelloWorld
存储原理
计算机中表示数据的最小单位:1字节(byte:B)=8位(bit:b) 1B=8b
二进制
二进制转十进制:
在java中,二进制以0B
或0b
开头
十进制
十进制转二进制,除二取余法
八进制/十六进制
为了便于观察和表示二进制,衍生出了八进制与十六进制
如:
|
|
在java中,八进制以0
开头,十六进制以0X
或0x
开头
字符存储
字符在底层存储的就是字符对应的ASCII的值
- a => 97
- A => 65
- 0 => 48
图片存储
图片就是无数个像素点组成的,每个像素点的数据用0~255*255*255表示颜色
运算符
基本运算符
+,-,*,/,%
注意:
+
符号与字符串运算的时候是用作连接符
使用的,能算则算,不能算则连接在一起
|
|
自增自减运算符
|
|
赋值运算符
+=,-=,*=,/=, %=
关系运算符
>,>=, <, <=,==,!=
逻辑运算符
符号 | 名称 | 运算逻辑 |
---|---|---|
& | 逻辑与 | 全为true,结果才为true |
| | 逻辑或 | 有一个为true,结果就为true |
! | 逻辑非 | |
^ | 逻辑异或 | 前后结果一致,返回false,前后结果不同,返回true |
&& | 短路与 | 左边只要出现false,右边就不执行 |
|| | 短路或 | 左边只要出现true,右边就不执行 |
三元运算符
|
|
运算符优先级
流程控制
分支结构
if分支结构
|
|
switch分支结构
通过比较值来决定执行哪条分支
|
|
执行流程
- 先执行表达式的值,再拿着这个值去与case后的值进行匹配
- 与哪个case后的值匹配为true,就执行哪个case块的代码,遇到break就跳出switch分支
- 如果全部case后的值与之匹配都是false,则执行default块的代码
注意事项
- 表达式类型只能是byte、short、int、char、jdk5开始支持枚举,jdk开始支持String、不支持double(计算机的二进制运算小数的方案本身就是不精确的)、float、long
- case给出的值不允许重复,且只能是字面量,不能是变量
- 正常使用switch的时候,不要忘记break,否则会出现穿透现象。
穿透现象不是一种bug,当存在多个case分支代码相同时,可以把相同的代码放到一个case块中,其他的case块都通过穿透性穿透到该case块执行代码即可,这样可以简化代码
|
|
循环结构
for循环结构
|
|
while循环结构
|
|
我们知道循环几次:使用for,不知道循环几次:使用while
do while循环
特点:先执行后判断
|
|
死循环
|
|
关键字
Break:跳出并结束当前所在循环的执行
continue:用于跳出当前循环的当次执行,直接进入循环的下一次执行
数组
数据就是一个容器,用来存一批同种类型的数据
定义
静态初始化数组
所谓静态数组就是:定义数组的时候直接给数组赋值
|
|
动态初始化数组
定义数组时先不存入具体的元素值,只确定数组存储的数据类型和数组的长度
|
|
动态初始化数组元素默认值规则:
数据类型 | 明细 | 默认值 |
---|---|---|
基本类型 | byte,short,char,int,long | 0 |
基本类型 | float,double | 0.0 |
基本类型 | boolean | false |
引用类型 | 类、接口、数组、string | null |
数组在内存中执行过程
java内存分配:
-
方法区(字节码文件加载到这里)
-
栈内存(方法运行时所进入的内存,变量也在这里)
特点:先进后出
-
堆内存(new出来的东西会在这块内存中开盘空间并产生地址)
特点:先进先出
注意
- 数组变量名中存储的是数组在内存中的地址,因此数组是一种
引用数据类型
- 多变量指向同一个数组对象时,多变量修改的都是同一个数组对象中的数据,如果某个数组变量存储的的地址是null,那么该变量将不再指向任何数组对象(该变量没有指向数组对象),而不是将数组对象修改为null
方法
方法是一种用于执行特定任务或操作的代码块,就是一个功能的集合,它可以接收数据进行处理,并返回一个处理后的结果
定义
标准定义格式
|
|
执行原理
方法被调用的时候,是进入到栈内存中运行
为什么方法要放到栈中执行
我们知道栈的一个特点:先进后出
这样就有2个好处:
- 确保方法调用其他方法后可以回来
- 确保方法执行完毕后可以释放栈内存
参数传递
基本类型和引用类型的参数传递都是值传递,不同的是基本数据类型的参数传输的是存储的数据值
的副本,而引用数据类型的参数传输存储的地址值
可变参数
就是一种特殊的形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称
特点
可以不传数据给它,可以传一个或同时传多个数据给它,也可以传一个数组给它
|
|
好处
常常用来灵活的接收数据
注意
- 可变参数在形参列表中只能出现一个
- 可变参数必须放到形参列表的 最后面
|
|
重载
一个类中,出现多个方法的名称相同,但是它们的形参列表是不同的,那么这些方法就称为方法重载了。
即:方法名称相同,形参不同(形参个数不同,形参类型不同,形参类型顺序不同)
注意
- 方法必须被调用才能执行
- 一个方法不能定义在另一个方法里
- 方法的返回值类型是void(无返回声明)时,方法内不能使用return返回数据
- return作用:立即跳出并结束当前方法的执行(语句的下面,不能编写代码,属于无效的代码,执行不到这儿),常用于
卫语句
拦截
包
包是分门别类管理程序的,类似于文件夹
建包语法
|
|
注意事项
- 同一个包下的类,可以互相直接调用
- 如果调用其他包下的程序,则必须要导包,才可以访问!导包格式:
import 包名.类名
- 如果调用的包名下的对象名重复,此时默认只能导入一个,另一个必须带包名访问
异常
程序可能出现的问题就是异常
常见异常
|
|
异常体系
Java.lang.Throwable -> Error
-> Exception -> RuntimeExcetion -> …
-> 其他异常
Error
:代表系统级错误(属于严重问题),我们开发人员不用管它。如:硬件内存不够
Exception
:代表我们程序可能会出现的问题,因此,我们通常会用Exception以及它的子类来封装程序出现的问题
- 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时会出现的异常(如:数据索引越界异常)
- 编译时异常:编译阶段就会出现错误提醒(如:日期解析异常)
编译异常处理2种方式
-
在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理
1 2 3
方法 throws 异常1,异常2...{ .... }
-
捕获异常(try…catch),直接捕获程序出现的异常
1 2 3 4 5 6 7
try{ // 监视可能出现异常的代码 }catch(异常类型1 变量){ // 处理异常 }catch(异常类型2 变量){ // 处理异常 }
作用
- 用来查询系统bug的关键参考信息
- 可以作为方法内部的一种特殊返回值,以便通知上层调用者底层的执行情况
|
|
异常处理
-
在最外层捕获异常,记录异常并响应合适的信息给用户
-
在最外层捕获异常,尝试重新修复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public static double getPrice(){ Scanner sc = new Scanner(System.in); System.out.println("请输入一个价格:"); return sc.nextDouble(); } // 处理输入不合法的异常 while(true){ try{ double price = getPrice(); System.out.println("本商品价格:"+price); break; } catch(Exception e){ System.out.println("您输入的价格不合法,请重新输入"); } }
自定义异常
为了处理,java无法提供的因自己企业面临的问题,而出现的技术,我们就称之为自定义异常类。
自定义运行异常
|
|
自定义编译异常
|
|
java在逐步抛弃编译异常(代码干扰太多),因此我们写异常尽量定义运行时异常