实用指南:Java基础11-面向对象高级:代码块、内部类、函数式编程、常见API
前言:
这个系列记录了我学习面向语言Java的完整过程,可以当作笔记使用。
每篇文章都包含可运行的代码示例和常见错误分析,尤其适合没有编程经验的读者。学习时建议先准备好安装JDK(Java Development Kit)和IDEA(IntelliJ IDEA集成开发环境),随时尝试修改示例代码。
一,代码块
1,什么是代码块:
![]()
2,代码块分两种:
静态代码块:
运行结果:

实例代码块:
运行结果:

二,内部类

1,成员内部类:
![]()
如何创建:![]()
示例:
运行结果:

拓展2示例:
2,静态内部类:
![]()
如何创建:

示例:


运行结果:

3,局部内部类:
4,匿名内部类:
示例:
1,不用匿名内部类时:
2,用匿名内部类时:
注:如果对接口创建匿名类也是同理。
匿名内部类开发场景:
当 API 或 GUI 框架的方法需要接收一个“接口实现类对象” 或 “抽象类子类对象” 作为参数时(本质是依赖抽象而非具体实现),而这个对象的逻辑只需要用一次,此时用匿名内部类是最简洁的选择 —— 它可以在传参的同时,直接完成 “定义子类 / 实现类 + 重写抽象方法 + 创建对象” 的全过程,避免了单独定义类的冗余。
示例:
调用sum公司写好的API,对数组(例如:Student[] students = new Student[6];)进行排序
// 需求:按年龄升序排序。可以调用sun公司写好的API直接对数组进行排序。
// public static void sort(T[] a, Comparator c)
// 参数一:需要排序的数组
// 参数二:需要给sort声明一个Comparator比较器对象(指定排序的规则)
// sort方法内部会调用匿名内部类对象的compare方法,对数组中的学生对象进行两两比较,从而实现排序。
Arrays.sort(students, new Comparator() {
@Override
public int compare(Student o1, Student o2) {
// 指定排序规则:
// 如果你认为左边对象 大于 右边对象 那么返回正整数。
// 如果你认为左边对象 小于 右边对象 那么返回负整数。
// 如果两边相等那么返回0。
// if(o1.getAge() > o2.getAge()){
// return 1;
// }else if(o1.getAge() < o2.getAge()){
// return -1;
// }
// return 0;
// return o1.getAge() - o2.getAge(); // 按照年龄升序!
return o2.getAge() - o1.getAge(); // 按照年龄降序!
}
});
三,函数式编程
1,Lambda表达式:
函数式接口是 “特殊的接口”:只能有且仅有 1 个抽象方法
函数式接口是接口的 “子集”,它必须满足:
- 是接口
- 抽象方法的数量 严格等于 1(可以有默认方法、静态方法,这些不算抽象方法)
如果一个接口有 2 个及以上抽象方法,就不是函数式接口。
示例:

2,Lambda表达式的省略规则:

示例:
JFrame win = new JFrame("登录窗口");
win.setSize(300, 200);
win.setLocationRelativeTo(null); // 居中显示。
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
win.add(panel);
JButton btn = new JButton("登录");
panel.add(btn);
//原本的匿名内部类
// btn.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// System.out.println("登录成功!");
// }
// });
//用Lambda简化
// btn.addActionListener((ActionEvent e) -> {
// System.out.println("登录成功!");
// });
//根据Lambda表达式省略规则,进一步省略,1,参数类型全部省略
// btn.addActionListener((e) -> {
// System.out.println("登录成功!");
// });
//2,参数列表只有一个参数,"()"可以省略
// btn.addActionListener(e -> {
// System.out.println("登录成功!");
// });
//3,表达式只有一行代码,"{}"不写同时省略";",有"return"语句,"return"可以省略
btn.addActionListener(e -> System.out.println("登录成功!"));
win.setVisible(true);
3,方法引用:
注:方法引用可遇不可求,不去人为故意简化
I、静态方法引用:

示例:
// 需求:按年龄升序排序。可以调用sun公司写好的API直接对数组进行排序。
Arrays.sort(students, (o1, o2) -> o1.getAge() - o2.getAge());
Arrays.sort(students, (o1, o2) -> Student.compareByAge(o1, o2));
Arrays.sort(students, Student::compareByAge);
// Student类中的静态比较方法:按年龄升序比较两个Student对象
public static int compareByAge(Student o1, Student o2) {
return o1.getAge() - o2.getAge(); // 年龄差为正整数时o1年龄更大,负整数时o2年龄更大,0则年龄相等
}
II、实例方法引用:

示例:
// 需求:按年龄升序排序。可以调用sun公司写好的API直接对数组进行排序。
Student t = new Student();
Arrays.sort(students, (o1, o2) -> t.compareByHeight(o1, o2));
Arrays.sort(students, t::compareByHeight);
// Student类中的实例比较方法:按身高升序比较两个Student对象
public int compareByHeight(Student o1, Student o2) {
// 按照身高比较
return Double.compare(o1.getHeight(), o2.getHeight());
}
III.特定类的方法引用:

示例:
public static void main(String[] args) {
String[] names = {"Tom", "Jerry", "Bobi", "曹操", "Mike",
"angela", "Dlei", "Jack", "Rose", "Andy", "caocao"};
// 把这个数组进行排序: Arrays.sort(names, Comparator)
// Arrays.sort(names); // 默认就是按照首字母的编号升序排序。
// 要求:忽略首字母的大小进行升序排序(java官方默认是搞不定的,需要我们自己指定比较规则)
// Arrays.sort(names, new Comparator() {
// @Override
// public int compare(String o1, String o2) {
// // java已经为我们提供了字符串按照首字母比较的方法:
// // java.lang.String类特有的方法:compareToIgnoreCase
// return o1.compareToIgnoreCase(o2);
// }
// });
//通过Lambda表达式以及对应的省略规则,代码化简为:
// Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
//通过特定类的方法引用,则是:
// 特定类的名称::方法
Arrays.sort(names, String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));
}
IV、构造器引用:

示例:
public class Demo4 {
public static void main(String[] args) {
// 目标:理解构造器引用。
// 创建了接口的匿名内部类对象
// CarFactory cf = new CarFactory() {
// @Override
// public Car getCar(String name) {
// return new Car(name);
// }
// }; //在Lambda表达式里只是在创建对象
// CarFactory cf = name -> new Car(name);
// 构造器引用: 类名::new
CarFactory cf = Car::new;
Car c1 = cf.getCar("奔驰");
System.out.println(c1);
}
}
@FunctionalInterface
interface CarFactory {
Car getCar(String name);
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Car {
private String name;
}
四,常见API
1,String:
String是什么,有什么用?

String创建字符串对象的方式:
示例:
输出结果:

String创建对象的区别:
示例:
图示:
String提供的常用方法:
案例展示:
开发验证码:
public class Test6 {
public static void main(String[] args) {
// 目标:生成验证码。
String code = getCode(4);//存入变量code
System.out.println(code);//然后输出
System.out.println(getCode(6));//直接输出
}
// 帮我生成指定位数的随机验证码返回,每位可能是大小写字母或者数字。
// 帮我用String变量记住全部要用到的字符。
public static String getCode(int n) {
// 1、定义一个变量记住所有字符。
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// 2、定义一个变量用于记住验证码的随机字符。
String code = "";
// 3、循环n次,每次生成一个随机字符,拼接成字符串。
for (int i = 0; i < n; i++) {
// 4、随机一个索引
int index = (int)(Math.random() * str.length()); // [0,1) * 50 = [0,49]
// 5、根据索引获取字符,拼接成字符串。
code += str.charAt(index);
}
// 6、返回验证码。
return code;
}
}
2,ArrayLIst:
什么是集合:
ArrayLIst集合学什么?
示例:
public static void main(String[] args) {
// 目标:掌握ArrayList集合的基本使用。
// 创建ArrayList对象,代表一个集合容器
ArrayList list = new ArrayList<>(); // 泛型定义集合。
// 添加数据
list.add("java");
list.add("java2");
list.add("java3");
list.add("赵敏");
System.out.println(list); // [java, java2, java3, 赵敏]
// 查看数据
System.out.println(list.get(0));// java
System.out.println(list.get(1));// java2
System.out.println(list.get(2));// java3
System.out.println(list.get(3));// 赵敏
System.out.println("-----------------------------");
// 遍历集合。
for (int i = 0; i < list.size(); i++) {
// i 0 1 2 3
String s = list.get(i);
System.out.println(s);
}
// 删除数据
System.out.println(list.remove(2)); // 根据索引删除,返回删除的元素。
System.out.println(list);// [java, java2, 赵敏]
System.out.println(list.remove("赵敏")); // 根据元素删除,返回是否删除成功。true/ false
System.out.println(list);// [java, java2]
// 修改数据
list.set(0, "java4");// 根据索引修改元素,返回修改前的元素。
System.out.println(list);// [java4, java2]
}






















浙公网安备 33010602011771号