从0开始学习Java+AI知识点总结-8.面向对象高级-代码块、内部类、Lambda、方法引用、String和ArrayList常用API
System.out.println("修改前:" + old + ",修改后:" + list);System.out.println("用户名或密码错误,剩余" + chance + "次机会");System.out.println("删除后:" + list);System.out.println("索引2的元素:" + elem);System.out.println("元素个数:" +
作为 Java 初学者,掌握面向对象高级特性是提升编程能力的关键一步。本文将系统梳理代码块、内部类、函数式编程(Lambda 与方法引用)及常用 API(String、ArrayList)的核心知识点,结合实例讲解,帮助你快速理解并上手实战。
一、代码块:类的 "初始化利器"
代码块是 Java 类的五大成分之一(成员变量、构造器、方法、代码块、内部类),用于完成类或对象的初始化工作,分为静态代码块和实例代码块两类。
1. 静态代码块
- 格式:使用static {}包裹代码
- 特点:当类加载时自动执行,且只执行一次(因为类只会加载一次)。
- 作用:初始化类的静态变量,或执行类级别的预处理操作。
示例:
public class Student { // 静态变量 private static String schoolName;
// 静态代码块:初始化静态变量 static { schoolName = "xxx"; System.out.println("静态代码块执行:初始化学校名称"); } } // 当Student类首次被使用时,静态代码块自动执行 |
2. 实例代码块
- 格式:使用{}直接包裹代码(无 static 关键字)
- 特点:每次创建对象时执行,且执行在构造器之前。
- 作用:初始化对象的实例变量,与构造器配合完成对象初始化。
示例:
public class Student { private String name; private int age;
// 实例代码块:初始化实例变量 { name = "默认姓名"; age = 18; System.out.println("实例代码块执行:初始化默认信息"); }
// 构造器 public Student() { System.out.println("构造器执行:创建对象"); } } // 测试 public class Test { public static void main(String[] args) { Student s1 = new Student(); // 实例代码块先执行,再执行构造器 Student s2 = new Student(); // 每次创建对象都执行实例代码块 } } |
二、内部类:类中的 "嵌套结构"
当一个类的内部包含另一个完整的事物,且该事物无需单独设计时,可将其定义为内部类。内部类分为成员内部类、局部内部类和匿名内部类。
1. 成员内部类
定义在类的成员位置(与成员变量、成员方法同级)的内部类,属于外部类的普通成员。
核心特点:
- 可直接访问外部类的实例成员和静态成员。
- 如需在内部类中获取外部类对象,使用外部类名.this。
创建对象格式:
外部类名.内部类名 对象名 = new 外部类().new 内部类(); |
示例:
// 外部类 public class Car { private String brand = "奔驰"; // 外部类实例变量
// 成员内部类 public class Engine { public void start() { // 直接访问外部类成员 System.out.println(brand + "发动机启动"); // 获取外部类对象 Car car = Car.this; System.out.println("外部类品牌:" + car.brand); } } } // 测试 public class Test { public static void main(String[] args) { // 创建成员内部类对象 Car.Engine engine = new Car().new Engine(); engine.start(); // 输出:奔驰发动机启动 外部类品牌:奔驰 } } |
2. 局部内部类(了解)
定义在方法、代码块或构造器等执行体中的内部类,作用域仅限于当前执行体,实际开发中使用较少(文档标注为 "鸡肋语法")。
示例:
public class Test { public void show() { // 局部内部类(仅在show()方法中有效) class LocalClass { public void print() { System.out.println("局部内部类方法"); } } // 创建局部内部类对象并使用 new LocalClass().print(); } } |
3. 匿名内部类:"简化子类对象创建" 的利器
匿名内部类是特殊的局部内部类,无需声明类名,本质是 "继承了某个类或实现了某个接口的子类对象",常用于快速创建子类对象。
核心特点:
- 格式:new 类或接口(参数...) { 重写方法体 };
- 立即创建一个子类对象,无类名(隐藏默认名称)。
- 常用于作为参数传递给方法,简化代码。
实战场景 1:接口实现简化
// 定义接口 public interface Swimming { void swim(); } public class Test { // 方法接收Swimming类型参数 public static void goSwim(Swimming s) { s.swim(); } public static void main(String[] args) { // 匿名内部类作为参数传递 goSwim(new Swimming() { @Override public void swim() { System.out.println("学生游泳飞快~"); } }); goSwim(new Swimming() { @Override public void swim() { System.out.println("老师游泳还行~"); } }); } } |
实战场景 2:排序逻辑定制
使用Comparator接口的匿名内部类实现数组排序:
import java.util.Arrays; import java.util.Comparator; public class Student { private String name; private int age; // 构造器、getter/setter省略 public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{name='" + name + "', age=" + age + "}"; } public static void main(String[] args) { Student[] students = { new Student("玛卡巴卡", 16), new Student("唔西迪西", 12), new Student("依古比古", 18) }; // 匿名内部类定义排序规则(按年龄升序) Arrays.sort(students, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.age - o2.age; // 前-后:升序;后-前:降序 } }); System.out.println(Arrays.toString(students)); // 输出:[Student{name='唔西迪西', age=12}, ...] } } |
三、函数式编程:Lambda 与方法引用
JDK 8 引入的函数式编程特性,可大幅简化代码,核心是Lambda 表达式和方法引用。
1. Lambda 表达式:简化匿名内部类
Lambda 表达式用于替代函数式接口的匿名内部类,让代码更简洁。
核心概念:
- 函数式接口:有且仅有一个抽象方法的接口,可通过@FunctionalInterface注解约束(编译时校验)。
- Lambda 格式:(形参列表) -> { 方法体代码 }
基本使用:简化函数式接口实现
以Swimming接口为例,对比匿名内部类与 Lambda:
// 匿名内部类方式 Swimming s1 = new Swimming() { @Override public void swim() { System.out.println("游泳~"); } }; // Lambda方式(简化后) Swimming s2 = () -> { System.out.println("游泳~"); }; |
Lambda 省略规则:
- 形参列表的参数类型可省略(编译器自动推断)。
- 若形参列表只有一个参数,可省略小括号()。
- 若方法体只有一行代码,可省略大括号{}和分号;,若有return需一并省略。
示例:简化排序逻辑
// 原匿名内部类排序 Arrays.sort(students, new Comparator<Student>() { @Override public int compare(Student o1, Student o2) { return o1.age - o2.age; } }); // Lambda简化(省略参数类型) Arrays.sort(students, (o1, o2) -> { return o1.age - o2.age; }); // 进一步简化(单行代码省略{}和return) Arrays.sort(students, (o1, o2) -> o1.age - o2.age); |
2. 方法引用:进一步简化 Lambda
当 Lambda 表达式仅调用一个已存在的方法,且参数传递关系一致时,可使用方法引用进一步简化。
四种引用类型:
类型 |
格式 |
使用场景 |
静态方法引用 |
类名::静态方法名 |
Lambda 体仅调用静态方法,参数一致 |
实例方法引用 |
对象名::实例方法名 |
Lambda 体仅调用实例方法,参数一致 |
特定类型方法引用 |
类名::实例方法名 |
第一个参数是方法调用者,其余参数是方法入参 |
构造器引用 |
类名::new |
Lambda 体仅创建对象,参数与构造器一致 |
示例:
import java.util.Arrays; import java.util.Comparator; // 静态方法引用 class StringUtil { public static int compareByLength(String s1, String s2) { return s1.length() - s2.length(); } } public class Test { public static void main(String[] args) { String[] strs = {"apple", "banana", "cat"};
// 静态方法引用:StringUtil::compareByLength Arrays.sort(strs, StringUtil::compareByLength); System.out.println(Arrays.toString(strs)); // [cat, apple, banana] // 特定类型方法引用(String类的compareTo方法) Arrays.sort(strs, String::compareTo); // 等价于(s1,s2)->s1.compareTo(s2) } } |
四、常用 API 实战:String 与 ArrayList
掌握常用 API 是 Java 开发的基础,这里重点梳理String和ArrayList的核心用法。
1. String 类:字符串处理神器
String用于封装字符串数据,提供丰富的字符串处理方法。
创建 String 对象的两种方式:
- 直接赋值:String s = "你好";(推荐,复用常量池对象)。
- 构造器创建:
String s1 = new String(); // 空字符串 String s2 = new String("hello"); // 基于字符串创建 String s3 = new String(new char[]{'a','b','c'}); // 基于字符数组创建 |
常用方法:
方法名 |
说明 |
public int length() |
获取字符串的长度返回(就是字符个数) |
public char charAt(int index) |
获取某个索引位置处的字符返回 |
public char[] toCharArray(): |
将当前字符串转换成字符数组返回 |
public boolean equals(Object anObject) |
判断当前字符串与另一个字符串的内容一样,一样返回true |
public boolean equalsIgnoreCase(String anotherString) |
判断当前字符串与另一个字符串的内容是否一样(忽略大小写) |
public String substring(int beginIndex, int endIndex) |
根据开始和结束索引进行截取,得到新的字符串(包前不包后) |
public String substring(int beginIndex) |
从传入的索引处截取,截取到末尾,得到新的字符串返回 |
public String replace(CharSequence target, CharSequence replacement) |
使用新值,将字符串中的旧值替换,得到新的字符串 |
public boolean contains(CharSequence s) |
判断字符串中是否包含了某个字符串 |
public boolean startsWith(String prefix) |
判断字符串是否以某个字符串内容开头,开头返回true,反之 |
public String[] split(String regex) |
把字符串按照某个字符串内容分割,并返回字符串数组回来 |
实战案例:登录功能
import java.util.Scanner; public class LoginDemo { private static final String USERNAME = "admin"; private static final String PASSWORD = "123456"; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int chance = 3; // 3次登录机会 while (chance > 0) { System.out.println("请输入用户名:"); String username = sc.next(); System.out.println("请输入密码:"); String password = sc.next(); if (USERNAME.equals(username) && PASSWORD.equals(password)) { System.out.println("欢迎进入系统!"); break; } else { chance--; if (chance > 0) { System.out.println("用户名或密码错误,剩余" + chance + "次机会"); } else { System.out.println("登录失败,已锁定"); } } } sc.close(); } } |
2. ArrayList:动态数组容器
ArrayList是 Java 中最常用的集合类,用于存储动态长度的元素(大小可变,功能丰富)。
核心用法:
- 创建对象:ArrayList<String> list = new ArrayList<>();(泛型指定存储元素类型)。
- 常用方法:
常用方法名 |
说明 |
public boolean add(E e) |
将指定的元素添加到此集合的末尾 |
public void add(int index,E element) |
在此集合中的指定位置插入指定的元素 |
public E get(int index) |
返回指定索引处的元素 |
public int size() |
返回集合中的元素的个数 |
public E remove(int index) |
删除指定索引处的元素,返回被删除的元素 |
public boolean remove(Object o) |
删除指定的元素,返回删除是否成功 |
public E set(int index,E element) |
修改指定索引处的元素,返回被修改的元素 |
实战案例:ArrayList 基本操作
import java.util.ArrayList; public class ArrayListDemo { public static void main(String[] args) { // 创建存储字符串的集合 ArrayList<String> list = new ArrayList<>(); // 添加元素 list.add("Java"); list.add("Python"); list.add("C++"); System.out.println(list); // [Java, Python, C++] // 插入元素 list.add(1, "JavaScript"); System.out.println(list); // [Java, JavaScript, Python, C++] // 获取元素 String elem = list.get(2); System.out.println("索引2的元素:" + elem); // Python // 修改元素 String old = list.set(3, "Go"); System.out.println("修改前:" + old + ",修改后:" + list); // [Java, JavaScript, Python, Go] // 删除元素 list.remove(0); System.out.println("删除后:" + list); // [JavaScript, Python, Go] // 集合大小 System.out.println("元素个数:" + list.size()); // 3 } } |
总结
本文梳理了 Java 面向对象高级的核心知识点,包括代码块的初始化逻辑、内部类的分类与应用、函数式编程的 Lambda 与方法引用简化技巧,以及常用 API(String、ArrayList)的实战用法。这些知识点是 Java 开发的基础,建议结合示例代码反复练习,逐步掌握其核心逻辑。
后续可进一步深入学习集合框架其他类(如HashMap、LinkedList)和 Stream 流等高级特性,不断提升 Java 编程能力!
更多推荐
所有评论(0)