Java实现函数指针

在Java8之后,当定义的接口中只有一个函数,可以用作函数指针。

比如,定义一个输入参数为String返回String的函数。

public interface TestFuncPoint {
    String run(String str);
}

那么如何使用呢?

比如,我们需要定义一个函数,接受一个函数指针,并使用这个函数指针。

public interface TestFuncPoint {
    String run(String str);
}

// 定义一个类,在runFunc中使用这个函数指针
public class Demo {
    void runFunc(TestFuncPoint funcPoint) {
         System.out.println(funcPoint.run("Ted"));
    }
}

public class Main {
    public static void main(String[] args) {
        Demo d = new Demo();
        // 将函数的具体实现,传入runFunc中
        d.runFunc(Main::funcImpl);
    }
    
    // 定义具体函数
    public static String funcImpl(String str) {
        return "hi " + str;
    }
}

这样操作就可以非常灵活的,将之前只能通过反射实现的业务逻辑,做的更高效、清楚。


比如有这样一个业务需求。根据用户选择的功能,运行某一函数。入参是一个String类型的功能名称(不一定是函数名)。

如果按照没有函数指针的话,我们需要反射实现。

public class Demo {
    Map<String, String> funcMap = new HashMap<>();

    public Demo() {
        init();
    }

    void init() {
        funcMap.put("叫我爸爸", "callBaBa");
        funcMap.put("叫我妈妈", "callMaMa");
        funcMap.put("叫我爷爷", "callYeYe");
    }

    public void call(String funcName) {
        // 通过反射获取具体实现函数
        String methodName = funcMap.get(funcName);
        if (methodName != null) {
            try {
                Method method = Demo.class.getMethod(methodName);
                method.invoke(this);
            } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }

    public void callBaBa() {
        System.out.println("爸爸!");
    }

    public void callMaMa() {
        System.out.println("妈妈!");
    }

    public void callYeYe() {
        System.out.println("爷爷!");
    }
}

public class Main {
    public static void main(String[] args) {
        Demo demo = new Demo();
        // 模拟用户输入了"叫我爸爸"
        demo.call("叫我爸爸");
    }
}

如果有函数指针的话,就可以使逻辑更加清楚,执行效率更快。

public interface TestFuncPoint {
    void run();
}

public class Demo {
    Map<String, TestFuncPoint> funcMap = new HashMap<>();

    public Demo() {
        init();
    }

    void init() {
        // 这里的值是指向具体函数的指针
        funcMap.put("叫我爸爸", this::callBaBa);
        funcMap.put("叫我妈妈", this::callMaMa);
        funcMap.put("叫我爷爷", this::callYeYe);
    }

    public void call(String funcName) {
        TestFuncPoint method = funcMap.get(funcName);
        if (method != null) {
            method.run();
        }
    }

    public void callBaBa() {
        System.out.println("爸爸!");
    }

    public void callMaMa() {
        System.out.println("妈妈!");
    }

    public void callYeYe() {
        System.out.println("爷爷!");
    }
}

public class Main {
    public static void main(String[] args) {
        Demo demo = new Demo();
        demo.call("叫我爸爸");
    }
}

同样的,也可以实现事件效果。

比如,按下一个按钮之后,打印按下了按钮

public interface Event {
    void run();
}

public class Demo {
    private Event event;
    public void submitEvent(Event event) {
        this.event = event;
    }

    void raiseEvent() {
        this.event.run();
    }
}

public class Main {
    public static void main(String[] args) {
        Demo d = new Demo();
        // 订阅事件
        d.submitEvent(Main::buttonPressed);
        // 模拟事件发生
        d.raiseEvent();
    }

    public static void buttonPressed() {
        System.out.println("按下了按钮");
    }
}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值