【数据结构】反射、枚举 和 lambda表达式
- 一、反射
-
- [1.1 反射的概念](#1.1 反射的概念)
- [1.2 反射的作用](#1.2 反射的作用)
- [1.3 反射相关的类(重要)](#1.3 反射相关的类(重要))
- [1.4 反射举例](#1.4 反射举例)
-
- [1.4.1 获得Class对象的三种方式](#1.4.1 获得Class对象的三种方式)
- [1.4.2 反射的使用](#1.4.2 反射的使用)
- 二、枚举
-
- [2.1 枚举的概念](#2.1 枚举的概念)
- [2.2 枚举的使用](#2.2 枚举的使用)
-
- [2.2.1 switch 语句](#2.2.1 switch 语句)
- [2.2.2 枚举的常用方法](#2.2.2 枚举的常用方法)
- 三、lambda表达式
-
- [3.1 Lambda表达式的语法](#3.1 Lambda表达式的语法)
- [3.2 函数式接口](#3.2 函数式接口)
- [3.3 Lambda表达式](#3.3 Lambda表达式)
一、反射
1.1 反射的概念
Java的反射(reflection)机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制;这种动态
获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射(reflection)机制。
1.2 反射的作用

1.3 反射相关的类(重要)

1.4 反射举例
1.4.1 获得Class对象的三种方式
在反射之前,需要做的第⼀步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的⽬的,即:在运⾏状态中,对于任意⼀个类,都能够知道这个类的所有属性和⽅法;对于任意⼀个对象,都能够调⽤它的任意⽅法和属性,既然能拿到那么,我们就可以修改部分类型信息。

java
package demo;
//反射实例
//通过反射 来实例化一个对象
class Student {
//私有属性name
private String name = "bit";
//公有属性age
public int age = 18;
//不带参数的构造⽅法
public Student(){
System.out.println("Student()");
}
private Student(String name,int age) {
this.name = name;
this.age = age;
System.out.println("Student(String,name)");
}
private void eat(){
System.out.println("i am eat");
}
public void sleep(){
System.out.println("i am pig");
}
private void function(String str) {
System.out.println(str);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test {
public static void main(String[] args) {
//获取class对象:3种方式
Class<?> c1 = null;
try {
//获取class对象 方式1:使用class.forname("类的全路径名")
c1 = Class.forName("demo.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
//获取class对象 方式2: 使⽤ .class ⽅法
Class<?> c2 = Student.class;
//获取class对象 方式3: 使⽤类对象的 getClass() ⽅法
Student student = new Student();
Class<?> c3 = student.getClass();
//获取的三个class对象 为同一个
System.out.println(c1 == c2);
System.out.println(c1 == c3);
System.out.println(c2 == c3);//true
}
}
1.4.2 反射的使用
java
package demo;
//通过反射来构造对象 调用Test里的方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectClassDemo {
//创建对象
public static void reflectNewInstance() {
Class<?> c1 = null;
try {
c1 = Class.forName("demo.Student");
Student student = (Student) c1.newInstance(); // 默认调用无参构造
System.out.println(student);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// 反射私有的构造⽅法 屏蔽内容为获得公有的构造⽅法
public static void reflectPrivateConstructor() {
try {
Class<?> classStudent = Class.forName("demo.Student"); // ✅ 使用全限定类名
Constructor<?> declaredConstructorStudent =
classStudent.getDeclaredConstructor(String.class, int.class); // ✅ 获取 private 构造方法
declaredConstructorStudent.setAccessible(true); // ✅ 允许访问 private 构造方法
Student student = (Student) declaredConstructorStudent.newInstance("lisi", 15); // ✅ 直接创建实例
System.out.println("获得私有构造方法且修改姓名和年龄:" + student);
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 反射私有属性
public static void reflectPrivateField() {
try {
Class<?> classStudent = Class.forName("demo.Student");
Field field = classStudent.getDeclaredField("name");
field.setAccessible(true);
//可以修改该属性的值
Object objectStudent = classStudent.newInstance();
Student student = (Student) objectStudent;
field.set(student,"⼩明");
String name = (String) field.get(student);
System.out.println("反射私有属性修改了name:"+ name);
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 反射私有⽅法
public static void reflectPrivateMethod() {
try {
Class<?> classStudent = Class.forName("demo.Student");
Method methodStudent =
classStudent.getDeclaredMethod("function",String.class);
System.out.println("私有⽅法的⽅法名为:"+methodStudent.getName());
//私有的⼀般都要加
methodStudent.setAccessible(true);
Object objectStudent = classStudent.newInstance();
Student student = (Student) objectStudent;
methodStudent.invoke(student,"我是给私有的function函数传的参数");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) {
reflectNewInstance();
reflectPrivateConstructor();
reflectPrivateField();
reflectPrivateMethod();
}
}
输出结果:

二、枚举
2.1 枚举的概念
枚举是在JDK1.5以后引⼊的。主要⽤途是:将⼀组常量组织起来,在这之前表示⼀组常量。
2.2 枚举的使用
2.2.1 switch 语句
java
package enumdemo;
public enum TestEnum {
RED,BLACK,GREEN;
public static void main(String[] args) {
TestEnum testEnum2 = TestEnum.BLACK;
switch (testEnum2) {
case RED:
System.out.println("red");
break;
case BLACK:
System.out.println("black");
break;
case GREEN:
System.out.println("black");
break;
default:
break;
}
}
}
输出结果:

2.2.2 枚举的常用方法

java
package enumdemo;
public enum TestEnum {
RED,BLACK,GREEN;//枚举对象
public static void main(String[] args) {
TestEnum[] testEnums = TestEnum.values();//Enum 为抽象类,不能实例化
for (int i = 0; i < testEnums.length; i++) {
System.out.println(testEnums[i]+" " + testEnums[i].ordinal());
}
System.out.println("===========");
TestEnum testEnum = TestEnum.valueOf("RED");//将普通字符串转化为枚举实例
System.out.println(testEnum);
int comp = RED.compareTo(BLACK);
System.out.println(comp);
}
重要:枚举的构造⽅法默认是私有的
java
public enum TestEnum {
RED("red",1),BLACK("black",2),WHITE("white",3),GREEN("green",4);
private String name;
private int key;
/**
* 1、当枚举对象有参数后,需要提供相应的构造函数
* 2、枚举的构造函数默认是私有的 这个⼀定要记住
* @param name
* @param key
*/
private TestEnum (String name,int key) {
this.name = name;
this.key = key;
}
public static TestEnum getEnumKey (int key) {
for (TestEnum t: TestEnum.values()) {
if(t.key == key) {
return t;
}
}
return null;
}
public static void main(String[] args) {
System.out.println(getEnumKey(2));//BLACK
}
}
三、lambda表达式
3.1 Lambda表达式的语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
java
// 1. 不需要参数,返回值为 2
() -> 2
// 2. 接收⼀个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的和
(x, y) -> x + y
// 4. 接收2个int型整数,返回他们的乘积
(int x, int y) -> x * y
// 5. 接受⼀个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
3.2 函数式接口
要了解Lambda表达式,⾸先需要了解什么是函数式接口,函数式接口定义:⼀个接口有且只有⼀个抽象⽅法 。

java
@FunctionalInterface
interface NoParameterNoReturn {
void test();
default void test2() {
System.out.println("JDK1.8新特性,default默认⽅法可以有具体的实现");
}
}
3.3 Lambda表达式
(1)⾸先,我们事先准备好⼏个接⼝:
java
//⽆返回值 ⽆参数
@FunctionalInterface
interface NoParameterNoReturn {
void test();
}
//⽆返回值 ⼀个参数
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
}
//⽆返回值 多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
}
//有返回值 ⽆参数
@FunctionalInterface
interface NoParameterReturn {
int test();
}
//有返回值 ⼀个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}
//有返回值 多参数
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}
(2)我们在上⾯提到过,Lambda可以理解为:Lambda就是匿名内部类的简化,实际上是创建了⼀个类,实现了接⼝,重写了接⼝的⽅法 。
没有使⽤lambda表达式的时候的调用方式:
java
public static void main(String[] args) {
NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {
@Override
public void test() {
System.out.println("hello");
}
};
/* new NoParameterNoReturn() {
@Override
public void test() {
}
};相当于匿名内部类*/
noParameterNoReturn.test();//hello
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return 0;
}
});
(3)使用lambda表达式调用
java
package lambdademo;
import java.util.Comparator;
import java.util.PriorityQueue;
//⽆返回值 ⽆参数
@FunctionalInterface
interface NoParameterNoReturn {
void test();
}
//⽆返回值 ⼀个参数
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
}
//⽆返回值 多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
}
//有返回值 ⽆参数
@FunctionalInterface
interface NoParameterReturn {
int test();
}
//有返回值 ⼀个参数
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
}
//有返回值 多参数
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}
public class Test {
public static void main3(String[] args) {
NoParameterReturn func = () -> 10; // 直接返回 10
int result = func.test(); // 调用并接收返回值
System.out.println(result); // 输出 10
System.out.println("=============");
OneParameterReturn oneParameterNoReturn = x -> x*2;
System.out.println(oneParameterNoReturn.test(5)); // 输出10
MoreParameterNoReturn moreParameterNoReturn = (int a,int b) -> {
System.out.println(a+b);
};
moreParameterNoReturn.test(1,2);//3
}
public static void main(String[] args) {
//lambda表达式
NoParameterNoReturn noParameterNoReturn = () -> {System.out.println("hello");};//hello
//OneParameterNoReturn oneParameterNoReturn = (a)->{System.out.println(a);};
OneParameterNoReturn oneParameterNoReturn = a->System.out.println(a);
oneParameterNoReturn.test(10);//10
//MoreParameterNoReturn moreParameterNoReturn = (int a,int b) -> {System.out.println(a+b);};
MoreParameterNoReturn moreParameterNoReturn = (a,b) -> {System.out.println(a+b);};
moreParameterNoReturn.test(1,2);//3
}
public static void main1(String[] args) {
NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {
@Override
public void test() {
System.out.println("hello");
}
};
/* new NoParameterNoReturn() {
@Override
public void test() {
}
};相当于匿名内部类*/
noParameterNoReturn.test();//hello
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return 0;
}
});
PriorityQueue<Integer> priorityQueue2 = new PriorityQueue<>((x, y) -> x.compareTo(y));
}
}