• 反射、枚举及lambda表达式


    目录

            前言:

            反射

            获取Class对象

            代码实现

            常用方法代码实现(有详细注释)

            优缺点

            枚举

            枚举基本操作代码实现

            优缺点

            Lambda表达式

            Lambda表达式基本使用代码

            优缺点

            小结:


    前言:

    🎈java提供的反射机制是一把双刃剑,它打破了我们对原有访问修饰限定符的认知。枚举是一个特殊的类,可以将一些可能出现的情况枚举出来,以便于我们使用。lambda表达式是对代码的一种简写,可以让代码足够简单。

    反射

    🤞javac编译产生的class文件,对于JVM来说是一个对象,然后JVM就可以解析这个对象。我们也可以通过代码的实现来获取这个Class对象。当我们拿到这个对象的时候,就可以通过反射机制应用到这个实例,甚至可以得到或者修改这个对象的成员方法和属性。使这个类成为一个动态类。

    获取Class对象

    注意:有三种可以获取Class对象的方法,最常用的是全路径法。

    代码实现

    1. package demo3;
    2. public class Test2 {
    3. public static void main(String[] args) {
    4. //通过对象获取Class对象
    5. Student student = new Student();
    6. Class c1 = student.getClass();
    7. //通过类名获取Class对象
    8. Class c2 = Student.class;
    9. //全路径法获取Class对象
    10. try {
    11. Class c3 = Class.forName("demo3.Student");
    12. } catch (ClassNotFoundException e) {
    13. throw new RuntimeException(e);
    14. }
    15. }
    16. }

    常用方法代码实现(有详细注释)

    1. package demo3;
    2. import java.lang.reflect.Constructor;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.InvocationTargetException;
    5. import java.lang.reflect.Method;
    6. public class Test {
    7. public static void main(String[] args) {
    8. try {
    9. //生成Class对象
    10. Class c = Class.forName("demo3.Student");
    11. //通过反射创建一个对象
    12. Student student2 = (Student) c.newInstance();
    13. //调用构造方法
    14. Constructor constructor = c.getDeclaredConstructor(int.class, String.class);
    15. //修改权限
    16. constructor.setAccessible(true);
    17. //实例化对象
    18. Student student1 = (Student)constructor.newInstance(21, "wuhao");
    19. System.out.println(student1);
    20. //反射成员属性
    21. Field field = c.getDeclaredField("name");
    22. //修改权限
    23. field.setAccessible(true);
    24. //实例化对象
    25. Student student3 = (Student) c.newInstance();
    26. //修改属性
    27. field.set(student3, "qq");
    28. //获取属性
    29. String name = (String) field.get(student3);
    30. System.out.println(name);
    31. //反射成员方法
    32. Method method = c.getDeclaredMethod("function", String.class);
    33. //获取方法名
    34. System.out.println(method.getName());
    35. //修改权限
    36. method.setAccessible(true);
    37. //实例化对象
    38. Student student4 = (Student) c.newInstance();
    39. //给方法传参
    40. method.invoke(student4, "ttt");
    41. } catch (ClassNotFoundException e) {
    42. throw new RuntimeException(e);
    43. } catch (InstantiationException e) {
    44. throw new RuntimeException(e);
    45. } catch (IllegalAccessException e) {
    46. throw new RuntimeException(e);
    47. } catch (NoSuchMethodException e) {
    48. throw new RuntimeException(e);
    49. } catch (InvocationTargetException e) {
    50. throw new RuntimeException(e);
    51. } catch (NoSuchFieldException e) {
    52. throw new RuntimeException(e);
    53. }
    54. }
    55. }

    优缺点

    优点: 

    😯对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。

    😯增加程序的灵活性和扩展性,降低耦合性,提高自适应能力。

    😯反射已经运用在了很多流行框架。

    缺点:

    😯使用反射会有效率问题。会导致程序效率降低。

    😯反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。

    枚举

    🎉枚举是一个特殊的类,它是将常量组织起来,默认继承Enum类。通过类名就可以直接获取枚举对象。枚举对象是不能被反射的。

    注意:当枚举对象具有参数后,需要提供构造方法,并且这个构造方法必须是私有的。

    枚举基本操作代码实现

    1. package enumDemo;
    2. //默认继承Enum类
    3. //枚举不能被反射
    4. public enum Colour {
    5. RED("aa", 10),BLACK("w", 20),GREEN("yy",50),WHITE("kk", 6);
    6. private String name;
    7. private int age;
    8. public static void main(String[] args) {
    9. Colour[] colours = Colour.values();
    10. for(int i = 0; i < colours.length; i++) {
    11. System.out.println(colours[i]);
    12. }
    13. }
    14. //枚举是一个类,通过类名就可以访问其中的枚举对象
    15. //构造方法必须是私有的
    16. //枚举对象在构造时,必须在后面调用构造方法。
    17. private Colour(String name, int age) {
    18. this.name = name;
    19. this.age = age;
    20. }
    21. }
    22. enum Color2 {
    23. //0 1 2 3
    24. RED,BLACK,GREEN,WHITE;
    25. public static void main(String[] args) {
    26. //将字符串转为枚举对象,需原来就包含此对象
    27. System.out.println(Color2.valueOf("WHITE"));
    28. //得到枚举实例
    29. Color2 color1 = Color2.RED;
    30. Color2 color2 = Color2.GREEN;
    31. System.out.println(color1.compareTo(color2));
    32. System.out.println(RED.compareTo(WHITE));
    33. System.out.println(WHITE.compareTo(BLACK));
    34. //用于switch case语句
    35. switch (RED) {
    36. case RED:
    37. System.out.println("aaaa");
    38. break;
    39. case BLACK:
    40. break;
    41. case GREEN:
    42. break;
    43. case WHITE:
    44. break;
    45. }
    46. //将枚举对象转换为数组
    47. Color2[] tmp = Color2.values();
    48. //获取枚举成员的索引位置
    49. System.out.println(tmp[2].ordinal());
    50. }
    51. }

    优缺点

    优点:

    😄枚举常量更简单安全 。

    😄枚举具有内置方法 ,代码更优雅。

    缺点:

    😄不可继承,无法扩展。

    Lambda表达式

    🪖Lambda表达式形式为:() -> {};。()内类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。{}内可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。

    🪖通常应用于函数式接口,和匿名内部类的简写。其实两者是一样的理解,应用于函数式接口其实就是匿名类实现了这个接口,然后简写了这个匿名类。

    🪖一些集合类的方法参数就是函数式接口去接收的,我们就可以用Lambda表达式。

    Lambda表达式基本使用代码

    1. package lambdaDemo;
    2. import java.util.*;
    3. //函数式接口,只有一个函数
    4. @FunctionalInterface
    5. interface MoreParameterReturn {
    6. int test(int a,int b);
    7. }
    8. public class LambdaDemo {
    9. public static void main(String[] args) {
    10. List list = new ArrayList<>();
    11. list.add(1);
    12. list.add(2);
    13. list.add(3);
    14. list.add(4);
    15. //lambda表达式()内为形参,->后面为函数体
    16. //用于函数式接口
    17. list.sort((o1, o2) -> o2 - o1);
    18. list.forEach(s -> System.out.println(s));
    19. HashMap map = new HashMap<>();
    20. map.put("wuhao", 8);
    21. map.put("www", 9);
    22. map.put("hhh",6);
    23. map.forEach((key, val) -> System.out.println(key +" " + val));
    24. }
    25. public static void main1(String[] args) {
    26. //匿名内部类
    27. PriorityQueue priorityQueue = new PriorityQueue<>(new Comparator() {
    28. @Override
    29. public int compare(Integer o1, Integer o2) {
    30. return o1 - o2;
    31. }
    32. });
    33. //lambda表达式用于对匿名内部类的简化
    34. PriorityQueue priorityQueue1 = new PriorityQueue<>((o1, o2) -> o1 - o2);
    35. MoreParameterReturn moreParameterReturn1 = new MoreParameterReturn() {
    36. @Override
    37. public int test(int a, int b) {
    38. return a + b;
    39. }
    40. };
    41. //lambda表达式()内为形参,->后面为函数体
    42. MoreParameterReturn moreParameterReturn = (a, b) -> a + b;
    43. System.out.println(moreParameterReturn.test(10, 20));
    44. }
    45. }

    优缺点

    优点:

    🤨有利于代码的简写。

    缺点:

    🤨代码可读性差。

    小结:

    🐵我们在实际写代码时可以去尝试利用这样语法,相信会加深对其的理解性。

  • 相关阅读:
    【机器学习&数据挖掘】基于ARIMA 自回归积分滑动平均模型的销售价格&库存分析报告 附完整python代码
    HDLBis-Fsm3s
    JAVA实现冒泡排序
    Arduino IDE的下载和安装
    Day58|单调栈part01:739. 每日温度、496. 下一个最大元素
    函数题14 习题6-3 使用函数输出指定范围内的完数 浙大版《C语言程序设计(第4版)》题目集
    Python 编程基础概念
    【校招VIP】“推推”产品项目课程:产品的规划和商业化分析
    BC35&BC95 ONENET MQTT(旧)
    WebGPU 工具分享 - WGSL 代码高亮插件(VSCode)与预处理工具
  • 原文地址:https://blog.csdn.net/weixin_62353436/article/details/127507606