【数据结构】反射、枚举 和 lambda表达式
【数据结构】反射、枚举 和 lambda表达式
- 一、反射
- 1.1 反射的概念
- 1.2 反射的作用
- 1.3 反射相关的类(重要)
- 1.4 反射举例
- 1.4.1 获得Class对象的三种方式
- 1.4.2 反射的使用
- 二、枚举
- 2.1 枚举的概念
- 2.2 枚举的使用
- 2.2.1 switch 语句
- 2.2.2 枚举的常用方法
- 三、lambda表达式
- 3.1 Lambda表达式的语法
- 3.2 函数式接口
- 3.3 Lambda表达式
一、反射
1.1 反射的概念
Java的反射(reflection)机制是在运⾏时检查、访问和修改类、接⼝、字段和⽅法的机制;这种动态
获取信息以及动态调⽤对象⽅法的功能称为java语⾔的反射(reflection)机制。
1.2 反射的作用
1.3 反射相关的类(重要)
1.4 反射举例
1.4.1 获得Class对象的三种方式
在反射之前,需要做的第⼀步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的⽬的,即:在运⾏状态中,对于任意⼀个类,都能够知道这个类的所有属性和⽅法;对于任意⼀个对象,都能够调⽤它的任意⽅法和属性,既然能拿到那么,我们就可以修改部分类型信息。
package demo;
//反射实例
//通过反射 来实例化一个对象class Student {//私有属性nameprivate String name = "bit";//公有属性agepublic 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);}@Overridepublic 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 反射的使用
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 语句
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 枚举的常用方法
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);}
重要:枚举的构造⽅法默认是私有的
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; }
// 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表达式,⾸先需要了解什么是函数式接口,函数式接口定义:⼀个接口有且只有⼀个抽象⽅法 。
@FunctionalInterface
interface NoParameterNoReturn {void test();default void test2() {System.out.println("JDK1.8新特性,default默认⽅法可以有具体的实现");}
}
3.3 Lambda表达式
(1)⾸先,我们事先准备好⼏个接⼝:
//⽆返回值 ⽆参数
@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表达式的时候的调用方式:
public static void main(String[] args) {NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn() {@Overridepublic void test() {System.out.println("hello");}};
/* new NoParameterNoReturn() {@Overridepublic void test() {}};相当于匿名内部类*/noParameterNoReturn.test();//helloPriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return 0;}});
(3)使用lambda表达式调用
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; // 直接返回 10int result = func.test(); // 调用并接收返回值System.out.println(result); // 输出 10System.out.println("=============");OneParameterReturn oneParameterNoReturn = x -> x*2;System.out.println(oneParameterNoReturn.test(5)); // 输出10MoreParameterNoReturn 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() {@Overridepublic void test() {System.out.println("hello");}};
/* new NoParameterNoReturn() {@Overridepublic void test() {}};相当于匿名内部类*/noParameterNoReturn.test();//helloPriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return 0;}});PriorityQueue<Integer> priorityQueue2 = new PriorityQueue<>((x, y) -> x.compareTo(y));}
}