【数据结构】反射、枚举 和 lambda表达式

【数据结构】反射、枚举 和 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));
    }
}
相关推荐
熟悉的新风景5 分钟前
springboot项目或其他项目使用@Test测试项目接口配置-spring-boot-starter-test
java·spring boot·后端
心平愈三千疾5 分钟前
学习秒杀系统-实现秒杀功能(商品列表,商品详情,基本秒杀功能实现,订单详情)
java·分布式·学习
玩代码36 分钟前
备忘录设计模式
java·开发语言·设计模式·备忘录设计模式
BUTCHER51 小时前
Docker镜像使用
java·docker·容器
岁忧1 小时前
(nice!!!)(LeetCode 面试经典 150 题 ) 30. 串联所有单词的子串 (哈希表+字符串+滑动窗口)
java·c++·leetcode·面试·go·散列表
CYRUS_STUDIO2 小时前
深入 Android syscall 实现:内联汇编系统调用 + NDK 汇编构建
android·操作系统·汇编语言
艾莉丝努力练剑2 小时前
【数据结构与算法】数据结构初阶:详解顺序表和链表(四)——单链表(下)
c语言·开发语言·数据结构·学习·算法·链表
LJianK12 小时前
Java和JavaScript的&&和||
java·javascript·python
RealmElysia3 小时前
java反射
java·开发语言
野蛮人6号3 小时前
黑马点评系列问题之p63unlock.lua不知道怎么整
java·redis·黑马点评