第一章 JavaSE入门
1、安装JDK
- 安装程序文件:jdk-17.0.8_windows-x64_bin.exe
- 安装操作要点:指定一个非中文无空格的目录作为安装目录
- 配置环境变量:JAVA_HOME指向bin目录的上一级
- 配置环境变量:Path取值%JAVA_HOME%\bin 注意:这里我们是把新内容追加到已有的Path值中,不是覆盖原来的值
- 验证:在命令行窗口运行命令java -version查看是否打印JDK版本
C:\Users\bamboo>java -version java version "17.0.8" 2023-07-18 LTS Java(TM) SE Runtime Environment (build 17.0.8+9-LTS-211) Java HotSpot(TM) 64-Bit Server VM (build 17.0.8+9-LTS-211, mixed mode, sharing)
2、安装IDEA
- 安装程序文件:idea-2026.2.0.1.exe
- 安装操作要点:指定一个非中文无空格的目录作为安装目录
3、第一段Java代码:HelloWorld
①核心要点
- Java的任何代码,都必须放在『类』中
- Java代码中,所有『指令、操作』性质、可以执行的代码都必须放在『方法(也就是函数)』中,比如:调用方法、数学计算、条件判断……
- 所有方法都必须放在类中
- Java代码中有一个特殊的方法:main,是整个程序的入口。我们打印HelloWorld的代码就写在main方法中
②操作步骤
-
打开IDEA
-
创建Project

-
在Project中创建module

-
在module中找到src目录,在src目录下创建package

-
在package下创建类

-
在类中声明main方法,快捷方式是:在类的大括号内打字输入main这个单词,然后直接回车

-
在main方法中编写打印字符串的代码,快捷方式是在main方法的大括号内输入sout,然后直接回车

-
在println()函数中传入字符串类型的参数,也就是我们要打印的内容
// Java中要把字符串用双引号括起来 System.out.println("Hello World!");
③程序结构示例

④最终程序代码示例
package com.atguigu.java.start;
public class Demo01_HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
⑤运行程序的操作
[1]第一步

[2]第二步

[3]运行结果

4、相关问题说明
如果看到生成的 main 方法是:
static void main(){
}
那就做如下操作:


5、数据类型
public class Demo02_DataType {
public static void main(String[] args) {
// 1、打印 byte 类型的数据
byte dataByte = 50;
System.out.println("byte 类型的数据 = " + dataByte);
// 2、打印 short 类型的数据
short dataShort = 200;
System.out.println("short 类型的数据 = " + dataShort);
// 3、打印 int 类型的数据
System.out.println("int 类型的数据:" + 50000);
// 4、打印 long 类型的数据
System.out.println("long 类型的数据:" + 99998888L);
// 5、打印 float 类型的数据
System.out.println("float 类型的数据:" + 8888.88f);
// 6、打印 double 类型的数据
System.out.println("double 类型的数据:" + 5555.55);
// 7、打印 char 类型的数据
System.out.println("char 类型的数据:" + '牛');
// 8、打印 boolean 类型的数据
System.out.println("boolean 类型的数据:" + true);
System.out.println("boolean 类型的数据:" + false);
}
}
6、标识符
public class Demo03_Identifier {
public static void main(String[] args) {
// 标识符不能使用非法字符
// int age@ = 10;
// 标识符首字母不能是数字
// int 5age = 10;
// 测试标识符严格区分大小写
int age = 10;
System.out.println("age = " + age);
int AGE = 18;
System.out.println("AGE = " + AGE);
// 不能使用关键字作为标识符
// int return = 10;
// 可以使用中文
int 年龄 = 100;
System.out.println("年龄 = " + 年龄);
// 同一个作用域(同一组大括号内)内,不能重复声明变量
// int age = 888;
// System.out.println("age = " + age);
}
}
7、变量
public class Demo04_Variable {
public static void main(String[] args) {
// 1、声明变量必须指定类型
int age = 10;
System.out.println("age = " + age);
// 2、变量的类型约束会一直存在
// age = false;
// 3、读取局部变量前必须初始化
int count;
count = 100;
System.out.println("count = " + count);
// 4、变量作用域在当前大括号范围内有效
System.out.println("age = " + age);
System.out.println("count = " + count);
// 5、final 修饰的变量只能赋值一次,成为常量
final int a = 11112222;
// a = 666;
System.out.println("a = " + a);
// 6、for 循环的小括号中声明的变量,仅限在 for 循环内使用
for (int i = 0; i < 10; i++) {
System.out.println("i = " + i);
}
// 循环外不能使用循环变量
// System.out.println("i = " + i);
}
public void doSth() {
// 当前方法内声明的同名变量和 main 方法中的没有任何关系
int age = 111;
int count = 666;
// age、count 都是在 main 方法中声明的,在另外的方法中不能使用
System.out.println("age = " + age);
System.out.println("count = " + count);
}
}
8、数据类型转换
public class Demo05_TypeConvert {
public static void main(String[] args) {
// 1、小类型转大类型
int a = 10;
System.out.println("a = " + a);
double b = a;
System.out.println("b = " + b);
// 2、大类型转小类型
double m = 10.8;
int n = (int)m;
System.out.println("n = " + n);
}
}
9、运算符
①数学运算
// 1、+号做数学运算
int a = 10;
int b = 5;
System.out.println(a + b);
// 2、+号做字符串连接
String info = "Tom's age is:";
int age = 18;
System.out.println(info + age);
int age = 10;
// 自增 1 的操作
age++; // age = age + 1;
System.out.println("age = " + age);
// 自减 1 的操作
age--; // age = age -1;
System.out.println("age = " + age);
// ++ 写在后面:先取值,后++
System.out.println("age = " + (age++)); // 10
System.out.println("age = " + age); // 11
// ++ 写在前面:先++,后取值
System.out.println("age = " + (++age)); // 12
// 经常用于循环变量的累加
// for(int i = 0; i < 10; i++) {
//
// }
②逻辑运算符
// 逻辑与
System.out.println(true && false); // false
System.out.println(true && true); // true
// 逻辑或
System.out.println(true || false); // true
System.out.println(false || false); // false
// 逻辑非(取反)
System.out.println(!true); // false
System.out.println(!false); // true
// 逻辑与的短路效果:&& 符号左边的值如果可以直接得到整个逻辑表达式的值,则 && 符号右边的判断代码就不会执行
int a = 10;
System.out.println((10 > 50) && (++a < 18)); // 10 > 50 返回 false 可以直接确定逻辑表达式为 false 触发短路
System.out.println("a = " + a);
System.out.println((100 > 50) || (++a < 18)); // 100 > 50 返回 true 可以直接确定逻辑表达式为 true 触发短路
System.out.println("a = " + a);
③三目运算符
int age = 20;
// 使用三目运算符进行判断:年龄大于等于 18 返回成年;年龄小于 18 返回未成年
System.out.println(age >= 18 ? "成年" : "未成年");
10、流程控制
①ifelse
int age = 89;
if (age < 18) {
System.out.println("未成年还不能上班~~~");
} else if (age >= 18 && age < 60) {
System.out.println("成年可以上班,还不能退休~~~");
} else {
System.out.println("老年可以退休~~~");
}
②switch
String season = "春天2222";
// 常规用法
switch (season) {
case "春天" -> System.out.println("春天,该播种了~~~");
case "夏天" -> System.out.println("夏天,该耕地了~~~");
case "秋天" -> System.out.println("秋天,该收获了~~~");
case "冬天" -> System.out.println("冬天,该打麻将了~~~");
default -> System.out.println("输入错误!!!"); // 前面各个分支都不匹配时执行
}
// 把 switch 整体作为一个表达式,让它最终返回一个确定的值
// 此时要求 switch 各个分支能够涵盖传入变量的所有情况的值,如果不能穷举所有值就通过 default 分支覆盖所有其它情况
String englishSeason = switch (season) {
case "春天" -> "Spring";
case "夏天" -> "Summer";
case "秋天" -> "Autumn";
case "冬天" -> "Winter";
default -> "输入错误~~~";
};
System.out.println("englishSeason = " + englishSeason);
③for循环
// 1、常规用法(快捷方式:fori回车)
for (int i = 0; i < 10; i++) {
System.out.println("i = " + i);
}
// 2、增强的 for 循环
// [1]创建一个数组
int[] nums = {5, 8, 11, 32, 67};
// [2]使用增强的 for 循环遍历(快捷方式:iter回车)
for (int n : nums) {
System.out.println("n = " + n);
}
④while循环
int age = 100;
while (age < 18) {
System.out.println("age = " + age + ",你还未成年!");
age++;
}
System.out.println("恭喜你!终于成年了!!!age = " + age);
System.out.println("~~~~~~~~~~~~~~~~~~~~~~");
do {
System.out.println("你还不能退休,继续上班!age = " + age);
age++;
} while (age < 60);
11、方法
①声明与调用
public static void main(String[] args) {
// 调用下面声明的方法
// 1、静态方法不必创建对象,可以通过类名直接调用。这个方法会返回一个字符串,我们声明一个变量来接收
String helloInfo = Demo15_Method.sayHello("齐天大圣");
System.out.println("helloInfo = " + helloInfo);
// 2、静态方法必须通过对象调用,所以我们需要先创建对象,再调用方法
// [1]创建方法所在类的对象
Demo15_Method demo = new Demo15_Method();
// [2]调用对象的方法
System.out.println(demo.sum(5, 10));
}
// 声明一个静态方法,功能是针对传入的姓名返回打招呼的字符串
public static String sayHello(String monkeyName) {
System.out.println("sayHello()函数执行了,传入的参数是:" + monkeyName);
return "Hello!" + monkeyName;
}
// 声明一个非静态方法,功能是把传入的两个整数加起来返回
public int sum(int i, int j) {
return i + j;
}
②方法的重载
public class Demo16_MethodOverload {
public static void main(String[] args) {
// 分别调用三个重载的方法
System.out.println(mul(5, 10));
System.out.println(mul(5.0, 10.0));
System.out.println(mul(5, 10, 10));
}
// 针对两个整数做乘法
public static int mul(int i, int j) {
System.out.println("针对两个整数做乘法");
return i * j;
}
// 针对两个小数做乘法
public static double mul(double i, double j) {
System.out.println("针对两个小数做乘法");
return i * j;
}
// 针对三个整数做乘法
public static int mul(int i, int j, int k) {
System.out.println("针对三个整数做乘法");
return i * j * k;
}
}
③可变参数
public static void main(String[] args) {
System.out.println(mul(1, 2, 3, 5, 10));
}
// 可变参数:传入参数的数量不确定
// 可变参数必须是整个参数列表中最后的位置
// 可变参数在整个参数列表中只能有一个
public static int mul(int initValue, int ... nums) {
int result = initValue;
// 在函数体内,可变参数会被当做数组来使用
for (int i = 0; i < nums.length; i++) {
result = result * nums[i];
}
return result;
}
12、数组
// 1、声明数组方式一
double[] scoreArray = new double[5];
for (int i = 0; i < scoreArray.length; i++) {
System.out.println("分数值:" + scoreArray[i]);
}
// 2、声明数组方式二
String[] nameArrary = {"小明", "小军", "小红", "小刚", "小牛", "小马"};
for (String name : nameArrary) {
System.out.println("name = " + name);
}
// 3、声明数组方式三
char[] charArray = new char[]{'A', 'W', 'E'};
for (char c : charArray) {
System.out.println("c = " + c);
}
// 4、错误的声明方式
// int[5] intArray = new int[]{1, 2, 3, 4, 5};
// 5、读取数组元素值
System.out.println("nameArrary 数组下标 2 的元素:" + nameArrary[2]);
// 6、把数据写入数组下标对应的位置
charArray[1] = 'Y';
System.out.println(charArray[1]);
// 7、下标值超过最后一个元素就会造成数组下标越界
// charArray[3] = 'T';
// 8、使用 Arrays 工具类提供的 toString() 方法直接打印数组元素值
// Arrays 需要导入才可以使用:import java.util.Arrays;
System.out.println(Arrays.toString(charArray));
第二章 面向对象
1、第一个Java类
需求:定义一个 Student 类,描述学生信息。
public class Student {
// 属性(也叫成员变量、字段)
String name;
int age;
String gender;
// 方法(行为)
public void study() {
System.out.println(name + " 正在学习");
}
public void introduce() {
System.out.println("我叫 " + name + ",今年 " + age + " 岁");
}
}
2、创建对象并使用
核心操作:
- 1、创建对象
- 2、设置属性
- 3、调用方法
public class DemoTest {
public static void main(String[] args) {
// 创建对象(new 关键字,类似 Python 的 Student())
Student s1 = new Student();
s1.name = "张三";
s1.age = 18;
s1.gender = "男";
// 调用方法
s1.introduce(); // 我叫 张三,今年 18 岁
s1.study(); // 张三 正在学习
// 再造一个对象
Student s2 = new Student();
s2.name = "李四";
s2.age = 20;
s2.introduce();
}
}
🔑 关键差异:
- Python:
obj = ClassName()- Java:
obj = new ClassName()(必须有new)
3、属性默认值
Java 给类的属性(成员变量)自动赋默认值,和局部变量不同:
| 类型 | 默认值 |
|---|---|
| 整数(byte/short/int/long) | 0 |
| 浮点(float/double) | 0.0 |
| 布尔(boolean) | false |
| 字符(char) | '\u0000' |
| 引用类型(String、数组、自定义类) | null |
Student s = new Student();
System.out.println(s.name); // null
System.out.println(s.age); // 0
System.out.println(s.gender); // null
Python 对照:Python 类属性必须显式赋值或用
__init__,没有"自动默认零"这回事。
4、方法传参:值传递
public static void main(String[] args) {
// 测试场景 1:给方法传递基本数据类型的参数
int value = 50;
add(value);
System.out.println("方法外打印:value = " + value);
// 测试场景 2:给方法传递引用类型的参数
int[] nums = {10, 20, 30};
incr(nums);
System.out.println("方法外打印下标 1 位置元素:" + nums[1]);
}
public static void add(int value) {
value = value + 100;
System.out.println("方法内打印:value = " + value);
}
public static void incr(int[] nums) {
// 给下标 1 这个位置的元素乘以 10,计算结果再重新赋值回下标 1 这个位置
nums[1] = nums[1] * 10;
System.out.println("方法内打印下标 1 位置元素:" + nums[1]);
}
5、构造器
public class Fish {
String fishName;
double fishPrice;
// 实际开发时为了避免没有无参构造器带来的各种问题,最好明确声明无参构造器!!!
public Fish() {
System.out.println("这里是一个无参构造器~~~");
}
// 创建一个包含两个参数的构造器
// 我们自定义了有参构造器,系统就不再提供无参构造器了!!!
public Fish(String fishName, double fishPrice) {
// 在构造器内部,使用外部参数给对象的属性赋值
// this 关键词:代表当前对象
// 当前局部变量和成员变量同名时,就可以使用 this. 写法区分二者
this.fishName = fishName;
this.fishPrice = fishPrice;
}
}
public class Demo03_FishTest {
public static void main(String[] args) {
// 1、调用自定义两个参数的构造器创建对象
Fish fish = new Fish("罗非鱼", 50.88);
System.out.println("fish.fishName = " + fish.fishName);
System.out.println("fish.fishPrice = " + fish.fishPrice);
// 2、调用无参构造器创建对象
// 我们自定义了有参构造器,系统就不再提供无参构造器了!!!
Fish fish2 = new Fish();
System.out.println("fish2.fishName = " + fish2.fishName);
System.out.println("fish2.fishPrice = " + fish2.fishPrice);
}
}
6、this
①调用其它构造器
public class Flower {
String flowerName;
double flowerPrice;
public Flower() {
// 通过 this 调用另一个有参的构造器
this("默认名称·郁金香", 66666.66);
System.out.println("无参构造器执行~~~");
// 效果和下面的代码等价:相当于简化代码
// this.flowerName = "默认名称·郁金香";
// this.flowerPrice = 66666.66;
}
public Flower(String flowerName, double flowerPrice) {
this.flowerName = flowerName;
this.flowerPrice = flowerPrice;
System.out.println("有参构造器执行~~~");
}
}
public class Demo04_FlowerTest {
public static void main(String[] args) {
// 无参构造器内部调用了另一个有参构造器
new Flower();
}
}
②实现方法连缀调用
public class Pig {
String pigName;
double pigPrice;
public void setPigName(String pigName) {
this.pigName = pigName;
}
public void setPigPrice(double pigPrice) {
this.pigPrice = pigPrice;
}
public Pig setPigNameSelf(String pigName) {
this.pigName = pigName;
return this;
}
public Pig setPigPriceSelf(double pigPrice) {
this.pigPrice = pigPrice;
return this;
}
}
public class Demo05_PigTest {
public static void main(String[] args) {
Pig pig = new Pig();
// 1、调用普通的 set 方法设置对象的属性
pig.setPigName("香香猪");
pig.setPigPrice(666.66);
// 2、用连缀调用的方式设置对象属性
pig.setPigNameSelf("金金猪")
.setPigPriceSelf(888.88);
}
}
7、封装性
①访问限制范围

②标准实体类
/**
* 实际开发时规范标准的实体类写法
* 成员变量全部使用 private 修饰
* 针对成员变量的读写操作,全部由 public 的 getXxx()、setXxx() 方法来执行(快捷方式:通过 Alt + Insert 调出 Generate 菜单)
* 必须提供无参的构造器(快捷方式:通过 Alt + Insert 调出 Generate 菜单)
* 有参构造器可选
* toString() 方法可选
*
* 从成员变量名称到 getter、setter 方法名是有确定性规则的:
* 成员变量名首字母大写然后前面加上 get 或 set
*/
public class Book {
private String bookName;
private double bookPrice;
private String author;
public Book() {
}
public Book(String bookName, double bookPrice, String author) {
this.bookName = bookName;
this.bookPrice = bookPrice;
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"bookName='" + bookName + '\'' +
", bookPrice=" + bookPrice +
", author='" + author + '\'' +
'}';
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public double getBookPrice() {
return bookPrice;
}
public void setBookPrice(double bookPrice) {
this.bookPrice = bookPrice;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
8、static
public class Demo07_TestStatic {
static {
System.out.println("静态代码块~~~在类被加载后执行~~~因为类只加载一次,所以静态代码块也只执行一次");
// 和 main() 方法一样,静态代码块也是一种静态上下文
// System.out.println(this);
}
static {
System.out.println("我是第二个静态代码块~~~");
}
{
System.out.println("非静态代码块~~~创建对象时执行~~~");
}
private String nonStaticValue = "非静态属性【我喜欢小动物~~~】";
private static String privateInfo = "Demo07_TestStatic类的静态成员变量【私有】";
public static String publicInfo = "Demo07_TestStatic类的静态成员变量【公共】";
public static void main(String[] args) {
// 读写静态私有成员变量
System.out.println("privateInfo = " + Demo07_TestStatic.privateInfo);
privateInfo = "修改静态成员变量的值【私有】";
System.out.println("privateInfo = " + Demo07_TestStatic.privateInfo);
// 读写静态公共成员变量
System.out.println("publicInfo = " + Demo07_TestStatic.publicInfo);
publicInfo = "修改静态成员变量的值【公共】";
System.out.println("publicInfo = " + Demo07_TestStatic.publicInfo);
// 可以通过对象访问静态属性,但没有必要,通过类名访问更简洁直接
Demo07_TestStatic demo07TestStatic = new Demo07_TestStatic();
demo07TestStatic.publicInfo = "AAA";
System.out.println("publicInfo = " + Demo07_TestStatic.publicInfo);
// 调用静态工具方法举例
System.out.println("-10的绝对值是:" + Math.abs(-10));
// 在静态上下文中不能访问非静态的资源
// 底层逻辑:静态上下文属于类级别的资源,在静态上下文中的代码执行时完全没有办法确定当前对应哪个对象,也可能尚未创建对象
// 而所有非静态资源都是和对象直接相关的、都是从属于某一个对象的!
// [1]非静态属性
// System.out.println("访问非静态属性:" + nonStaticValue);
// [2]this
// System.out.println("访问this关键词:" + this);
// [3]调用非静态方法
// showInfo();
// 创建当前类的对象,查看非静态代码块是否执行
new Demo07_TestStatic();
new Demo07_TestStatic();
new Demo07_TestStatic();
}
public void showInfo() {
}
}
9、综合练习
需求见PPT
public class Student {
// 全局范围内做数据统计非常适合使用静态变量来实现
private static int totalStudents = 0;
private String name;
private int age;
// 无参构造器
public Student() {
// 调用另外那个有参的构造器
this("默认的学生姓名", 0);
}
// 有参构造器
public Student(String name, int age) {
this.name = name;
this.age = age;
// 累加学生对象的数量:每创建一个对象,就给总数量 +1
totalStudents++;
}
// 返回当前学生总数
public static int getTotalStudents() {
return totalStudents;
}
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;
}
}
public class Demo08_StudentTest {
public static void main(String[] args) {
// 1、调用无参构造器创建 Student 对象
Student student01 = new Student();
// 2、调用有参构造器创建 Student 对象
Student student02 = new Student("王小明", 50);
// 3、调用 setter 方法给第一个 Student 对象设置属性值
student01.setName("王大明");
student01.setAge(18);
// 4、调用 getter 方法获取第一个和第二个 Student 对象的属性值
System.out.println("学生姓名:" + student01.getName());
System.out.println("学生年龄:" + student01.getAge());
System.out.println("学生姓名:" + student02.getName());
System.out.println("学生年龄:" + student02.getAge());
// 5、在 for 循环中创建多个 Student 对象
for (int i = 0; i < 10; i++) {
new Student();
}
// 6、获取学生对象总数
int totalStudents = Student.getTotalStudents();
System.out.println("学生对象总数 = " + totalStudents);
}
}
10、声明一个常量
public class Demo09_Constant {
// 定义一个常量,方便在整个项目中随时随地访问和使用
public static final String GLOBAL_INFO = "小明是个好同学~~~";
public static void main(String[] args) {
System.out.println(GLOBAL_INFO);
}
}
public class Demo20_TestConstant {
public static void main(String[] args) {
System.out.println(Demo09_Constant.GLOBAL_INFO);
}
}