Java SE
本文仅供自己复习回顾使用,不适用于零基础小白!
1. 前言
1.1 Java语言的发展
Java的第六个版本直接从1.4版本跳到了Java5.0,此后Java从小版本的更新变为了大版本的更新,每半年更新一次以适应市场需求,为了避免频繁的版本更新对开发者造成不必要的麻烦,其中几个版本被指定为LTS长期支持版本(Java8、11、17、21),其余版本称为过渡版本。
1.2 Java的三种分类
- Java SE(是后两种的基础)
- Java ME(已凉)
- Java EE(企业级开发)
JavaEE主要技术
广义的 Java EE 包含各种框架,其中最重要的就是 Spring 全家桶。Spring 诞生之初是为了改进 Java EE 开发的体验,后来逐渐成为了 Java Web 开发的实际标准。
JavaEE 号称有十三种核心技术。它们分别是:JDBC、JNDI、EJB、RMI、Servlet、JSP、XML、JMS、Java IDL、JTS、JTA、JavaMail和JAF。
1.3 Java的特性
其中跨平台是指能在Windows、Mac、Linux上运行同样的代码,一次编译,处处运行。
1.4 Java的运行方式
Java是混合型的语言,先把.java文件编译为.class字节码文件,再按行去翻译执行,执行不是在系统中直接运行,而是运行在虚拟机(JVM)中。
1.5 JDK与JVM
1.6 Java下载与安装
①就是下载JDK。找到Java官网下载页面,可以下载新版和历史版本的JDK。
②往下翻,找到exe的安装包。这里下的是Java 21,因为它是LTS长期支持版本。
③下载后双击安装到不含中文的路径下即可。
ps: 其中bin目录下含有javac和java的可执行程序。
④配置环境变量
配置环境变量有两种方式,第一种就是直接把java安装目录的bin目录路径直接添加到path中,但这样可能会修改到其他程序的环境变量,所以不推荐,下面是方式二:
设置搜索环境变量
添加JAVA安装目录路径为JAVA_HOME(不带bin)
双击Path,添加%JAVA_HOME%\bin
1.7 IDEA配置jdk
IDEA的下载不在多说,而配置jdk如下:
找到Project Structure中的SDKs,点击加号选择jdk安装目录即可。
2. 入门
2.1 注释和关键字
单行注释://
多行注释:/* */
文档注释:/** */
关键字就是被Java赋予了特殊含义的词,如public、class等。
关键字的字母全部小写。
2.2 字面量
在程序中直接写出来的值就是字面量,它不是根据条件动态生成的,比如3就是个int类型的字面量,'a'就是个char类型字面量。它是明确的,不需要额外计算的。
2.3 数据类型
数据类型分为基本数据类型和引用数据类型。String和数组都不是基本数据类型!!!它们被视为一个类。
基本数据类型(八种)
byte a = 1;short b = 2;int c = 3;long d = 4L; //定义long后面加Lfloat e = 5.0F; //定义float类型后面加Fdouble f = 6.0;char g = 'A';boolean h = true;
- 其中需要记住byte的取值范围为-128到127。
- 范围上double>float>long>int>short>byte。
- 定义long和float时需加后缀,大小写均可但推荐大写。
如何记忆取值范围?如short,它是16位二进制数据以补码的形式存在,第一位为符号位,而补码没有负零,即零唯一,所以它的取值范围为1000000000000000到0111111111111111,分别表示-32768和32767。(0为0000000000000000,所以负数能比整数多表示一位),即~
引用数据类型
对于基本数据类型而言,其变量数据直接存储在栈内存中;对于引用型数据类型,其变量的是数据部分则存储于堆中,栈内引用的是数据在堆内存中的数据,所以称为引用数据类型。(堆是由程序员通过代码显式分配(如 new
操作符),由垃圾回收机制(GC)自动回收。New出来的都是引用数据类型)
int[] arr1 = {1,2,3};int[] arr2 = arr1;arr1[1]=100;System.out.println(arr2[1]);//输出为100
2.4 标识符
标识符(Identifier)是编程语言中用来命名变量、函数、类或其他用户自定义元素的名称。它相当于程序中“名字”的角色,用于标识某个具体的东西。
标识符命名规则:
- 只能由数字、字母、下划线、美元符号($)组成
- 不能以数字开头
- 不能是关键字
- 区分大小写
标识符命名方法(核心是要见名知意):
- 变量命名:变量是一个单词,直接写。如name。
- 变量命名:变量是多个单词,用小驼峰命名法(首字母小写),如loadFile。
- 类命名:无论变量是几个单词,都用大驼峰命名法(首字母大写),如LoadFile。
2.5 Java导包与键盘录入
要实现键盘录入功能,无需自己手动写具体的与键盘交互的代码,这些Java已经做好了并封装在核心类库中,只要会用即可。该方法被封装在一个名为Scanner的类中。
调用步骤有三步:
- 导包
- 创建对象
- 调用对象的录入方法
// 1. 导包,导入键盘录入的核心类库
import java.util.Scanner;public class t1 {public static void main(String[] args) {// 2. 创建Scannner对象Scanner sc = new Scanner(System.in);// 3. 调用Scanner类的nextInt方法,表示从键盘输入一个int类型数据System.out.println("请输入一个整数:");int a = sc.nextInt();System.out.println(a);}
}
Scanner常用用法:
- nextLine() 读取一整行输入,包括空格,返回String。
- next() 读取一个单词(以空格为分隔符),返回String。
- nextInt() 读取下一个整数,返回整数(
int
)。 - nextDouble() 读取下一个双精度浮点数。
- nextBoolean() 读取下一个双精度浮点数。
- hasNext() 检查是否还有下一个输入项(例如下一个单词),返回Boolean。
- hasNextInt() 检查下一个输入是否为整数,返回Boolean。
- hasNextLine() 检查是否还有下一行输入,返回Boolean。
- nextFloat() 读取下一个长整数(
long
类型),返回Long。 - close() 关闭
Scanner
对象,释放资源。
2.6 IDEA项目结构
- 项目 是最高层级,包含所有代码、配置和资源。
- 模块 是逻辑划分,例如用户模块、商品模块和订单模块。
- 包 是物理组织形式,用于在模块中进一步划分功能和代码。
- 类 是功能的最小单位,完成具体的任务。
- 模块就是不同大区域功能的实现,如订单管理模块、用户模块、商品模块。
- 包是在模块下进一步细分的单位,如用户模块中可能既有业务逻辑,也有工具类,还有模型类。如果所有代码都堆在一个包里,会显得杂乱无章。通过分包,可以按逻辑职责划分代码,比如:
models
:存放用户数据结构(如User
类)。services
:存放业务逻辑(如UserService
)。controllers
:存放控制层代码(如UserController
,处理用户的请求)。
在建立项目之后就可以建立模块,模块里会包含一个src目录,在该目录下可以创建package包,包名一般为公司域名反写,如com.google.service和com.google.dao和com.google.utils等,在对应包下开发具体实现代码(class)即可。
编写代码时要在文件中写上包名:
3. 运算符
3.1 隐式转换和强制转换
隐式转换(自动类型提升)
两个数据进行运算时,如果数据类型不一样,必须先转为一样才能算。隐式转换是程序自动进行的,它把数据从表示范围小的转为表示范围大的。
如int a = 0; double b = 1.0; double c = a + b;这里的隐式转换就是a先提升为double再与b相加。
byte、short、char在运算前会先转为int类型,因为int是数字的默认数据类型。
强制转换(大范围转小范围)
long a = 10; int b = (int) a;
3.2 字符串的加操作(拼接)
字符串的加操作是从左到右运行的,如:
①
System.out.println(1+3+"我爱你");
输出:"4我爱你";
②
int age = 18; System.out.println("永远"+age+"岁");
输出:"永远18岁";
3.3 字符的加操作(拼接)
字符在运算前会先提升为int,提升的结果就是其对应为ASCII表中的值。
char a = 'a'; int b = 1; System.out.println(a+b);
输出:98; (a的ASCII值为97)
3.3 自增自减运算符
++a和a++一个是先加一个后加。
3.4 逻辑运算符与短路逻辑运算符
逻辑运算符(不常用)
短路逻辑运算符(常用)
具有短路效果,只有运算符左边式子能确定整个式子结果,右边式子就不会再执行。
如条件1&&条件2,只要条件1为false,直接为false。条件1||条件2,只有条件1为true直接为true。
常用:&& 、||、 !;
3.5 三元运算符
关系表达式?表达式1:表达式2;
关系表达式成立则结果为表达式1的结果,否则为表达式2的结果。
4. 数组(Array)
数组在存储数据时需要结合隐式转换,如一个int数组不能存一个float数据,但一个float数组可以存int,因为int会先隐式转换为float再存入。
但建议容器类型如数据类型保持一致。
4.1 数组的定义与静态初始化
静态初始化
int[] array1 = {1,2,3};
获取数组元素:array1[0];
数组元素修改:array[0] = 13;
4.2 数组的动态初始化
自己手动指定数组长度,再赋值,没赋值的区域由默认值填充,不同类型的数组,其默认值不同,其中int数组的默认初始值为0;
int[] array1 = new int[50];array1[0] = 1;for(int num : array1) {System.out.println(num);}
4.3 数组的遍历
①传统方式(快捷键:数组名.fori)
for (int i = 0; i < array1.length; i++) {System.out.println(array1[i]);}
②增强for循环
for(int num : array1) {System.out.println(num);}
4.4 二维数组
利用双重增强for循环遍历二维数组(这里利用静态初始化创建二维数组):
int[][] a = {{1,2,3},{4,5,6}};for(int[] ob : a){for(int ob2 : ob){System.out.println(ob2);}}
5. 方法
5.1 方法的定义
5.2 方法的重载
重载指的是在同一个类中(不在同一个类中不构成重载关系),允许定义多个具有相同名称但参数不同的方法。重载的方法可以通过不同的参数类型、数量或顺序来区分。如:
public class OverloadExample {// 重载方法1:没有参数public void printMessage() {System.out.println("Hello, World!");}// 重载方法2:一个整型参数public void printMessage(int x) {System.out.println("Number: " + x);}// 重载方法3:两个参数,一个是整数,另一个是字符串public void printMessage(int x, String y) {System.out.println("Number: " + x + ", Message: " + y);}public static void main(String[] args) {OverloadExample example = new OverloadExample();example.printMessage(); // 调用第一个方法example.printMessage(42); // 调用第二个方法example.printMessage(42, "Hello!"); // 调用第三个方法}
}
在调用时,会调用符合传参类型的那个方法。
6. 类与面向对象
面向对象三大特征:封装、继承、多态。
6.1 类的组成
- 成员变量
- 成员方法
- 构造方法
- 代码块
- 内部类
public class Person {String name;int age;// 构造方法public Person(String name, int age) {this.name = name;this.age = age;}// 修改名字的方法public void setName(String newName) {this.name = newName;}// 获取名字的方法public String getName() {return name;}// 方法:自我介绍public void sayHello() {System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");}// 程序主入口public static void main(String[] args) {int[][] a = {{1,2,3},{4,5,6}};for(int[] ob : a){for(int ob2 : ob){System.out.println(ob2);}}}
}
}
6.2 JavaBean类
前面写的带main方法的类叫做测试类,与之对应的是JavaBean类不带main方法,如:
import java.io.Serializable;public class Person implements Serializable {private static final long serialVersionUID = 1L;// 私有属性private String name;private int age;// 无参构造方法public Person() {}// 带参构造方法public Person(String name, int age) {this.name = name;this.age = age;}// Getter 和 Setter 方法public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}// 重写 toString 方法,便于测试输出@Overridepublic String toString() {return "Person{name='" + name + "', age=" + age + "}";}
}
6.3 private权限修饰符与Getter、Setter方法(成员变量)
Getter方法用于返回当前类的属性值,Setter用于设置当前类的属性值。
大多数时候,我们不希望可以直接通过girlFriend.age=100;这样直接去修改类的属性的值,可以用private修饰,表示只能被当前类中的方法修改,如果要修改,就自己先定义好Getter和Setter方法,用public修饰,到时候调用该方法来修改。(可以右键点击Generate,快速生成Getter和Setter)如:
package com.google.utils;public class VerifyOrder {private int order;private int quantity;private int price;public int getOrder() {return order;}public void setOrder(int order) {this.order = order;}public void setQuantity(int quantity) {this.quantity = quantity;}public void setPrice(int price) {this.price = price;}public int getQuantity() {return quantity;}public int getPrice() {return price;}
}
6.4 构造方法
成员方法是用于具体实现相应功能的方法,构造方法是用于构造类的时候要调用的方法,每次用new Student()创建一个类时都会调用。它分为无参构造方法和有参构造方法。
private int order;private int quantity;private int price;// 无参构造方法public VerifyOrder() {}// 有参构造方法public VerifyOrder(int order, int quantity, int price) {this.order = order;this.quantity = quantity;this.price = price;}
其中无参构造方法写不写都行,不写的话Java在运行时会自动生成一个无参构造方法。