反射、枚举及lambda表达式

目录

        前言:

        反射

        获取Class对象

        代码实现

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

        优缺点

        枚举

        枚举基本操作代码实现

        优缺点

        Lambda表达式

        Lambda表达式基本使用代码

        优缺点

        小结:


前言:

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

反射

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

获取Class对象

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

代码实现

package demo3;
public class Test2 {
    public static void main(String[] args) {
        //通过对象获取Class对象
        Student student = new Student();
        Class<?> c1 = student.getClass();

        //通过类名获取Class对象
        Class<?> c2 = Student.class;

        //全路径法获取Class对象
        try {
            Class<?> c3 = Class.forName("demo3.Student");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

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

package demo3;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
    public static void main(String[] args) {
        try {
            //生成Class对象
            Class<?> c = Class.forName("demo3.Student");
            //通过反射创建一个对象
            Student student2 = (Student) c.newInstance();
            //调用构造方法
            Constructor<?> constructor =  c.getDeclaredConstructor(int.class, String.class);
            //修改权限
            constructor.setAccessible(true);
            //实例化对象
            Student student1 = (Student)constructor.newInstance(21, "wuhao");
            System.out.println(student1);

            //反射成员属性
            Field field = c.getDeclaredField("name");
            //修改权限
            field.setAccessible(true);
            //实例化对象
            Student student3 = (Student) c.newInstance();
            //修改属性
            field.set(student3, "qq");
            //获取属性
            String name = (String) field.get(student3);
            System.out.println(name);

            //反射成员方法
            Method method = c.getDeclaredMethod("function", String.class);
            //获取方法名
            System.out.println(method.getName());
            //修改权限
            method.setAccessible(true);
            //实例化对象
            Student student4 = (Student) c.newInstance();
            //给方法传参
            method.invoke(student4, "ttt");

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }
}

优缺点

优点: 

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

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

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

缺点:

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

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

枚举

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

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

枚举基本操作代码实现

package enumDemo;
//默认继承Enum类
//枚举不能被反射
public enum Colour {
    RED("aa", 10),BLACK("w", 20),GREEN("yy",50),WHITE("kk", 6);
    private String name;
    private int age;

    public static void main(String[] args) {
        Colour[] colours = Colour.values();
        for(int i = 0; i < colours.length; i++) {
            System.out.println(colours[i]);
        }
    }

    //枚举是一个类,通过类名就可以访问其中的枚举对象
    //构造方法必须是私有的
    //枚举对象在构造时,必须在后面调用构造方法。
    private Colour(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
enum Color2 {
    //0 1 2 3
    RED,BLACK,GREEN,WHITE;

    public static void main(String[] args) {
        //将字符串转为枚举对象,需原来就包含此对象
        System.out.println(Color2.valueOf("WHITE"));
        //得到枚举实例
        Color2 color1 = Color2.RED;
        Color2 color2 = Color2.GREEN;
        System.out.println(color1.compareTo(color2));
        System.out.println(RED.compareTo(WHITE));
        System.out.println(WHITE.compareTo(BLACK));
        //用于switch case语句
        switch (RED) {
            case RED:
                System.out.println("aaaa");
                break;
            case BLACK:
                break;
            case GREEN:
                break;
            case WHITE:
                break;
        }
        //将枚举对象转换为数组
        Color2[] tmp = Color2.values();
        //获取枚举成员的索引位置
        System.out.println(tmp[2].ordinal());
    }
}

优缺点

优点:

😄枚举常量更简单安全 。

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

缺点:

😄不可继承,无法扩展。

Lambda表达式

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

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

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

Lambda表达式基本使用代码

package lambdaDemo;

import java.util.*;

//函数式接口,只有一个函数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a,int b);
}
public class LambdaDemo {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        //lambda表达式()内为形参,->后面为函数体
        //用于函数式接口
        list.sort((o1, o2) -> o2 - o1);
        list.forEach(s -> System.out.println(s));
        HashMap<String, Integer> map = new HashMap<>();
        map.put("wuhao", 8);
        map.put("www", 9);
        map.put("hhh",6);
        map.forEach((key, val) -> System.out.println(key +" " + val));

    }
    public static void main1(String[] args) {
        //匿名内部类
        PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        //lambda表达式用于对匿名内部类的简化
        PriorityQueue<Integer> priorityQueue1 = new PriorityQueue<>((o1, o2) -> o1 - o2);
        MoreParameterReturn moreParameterReturn1 = new MoreParameterReturn() {
            @Override
            public int test(int a, int b) {
                return a + b;
            }
        };
        //lambda表达式()内为形参,->后面为函数体
        MoreParameterReturn moreParameterReturn = (a, b) -> a + b;
        System.out.println(moreParameterReturn.test(10, 20));
    }
}

优缺点

优点:

🤨有利于代码的简写。

缺点:

🤨代码可读性差。

小结:

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

  • 30
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小太空人w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值