大白话之Java级联调用:一个类,一条语句,同时调用好几个方法,串成一串

前言

之前偶然学习了一下Dart编程语言(不是重点),在学习官方手册时发现一个新的概念:级联调用。这是啥东西?

于是我百度了以后,发现在Java中也有类似的级联调用,那它们的区别又在哪儿呢?

-📚-|需要先了解的知识|-📚-

语言 内容 链接
Java 类、方法、变量 null

-⭐️-|评分|-⭐️-

知识等级 实用性 罕见性
基础 实用 少见

上手

级联调用很简单,只要稍微分析下下面的源码,就懂了。

!级联

首先我们不用级联来实现:

 1public class 级联 {
 2    public static void main(String[] args) {
 3        //实例化Guys
 4        Guys guys = new Guys();
 5	//执行方法
 6        guys.boy();
 7        guys.girl();
 8        guys.gentleman();
 9        guys.lady();
10    }
11}
12
13class Guys {
14    public void girl() {
15        System.out.println("Hey, girl!");
16    }
17
18    public void boy() {
19        System.out.println("Oh, boy!");
20    }
21
22    public void lady() {
23        System.out.println("Greetings, lady!");
24    }
25
26    public void gentleman() {
27        System.out.println("Nice to meet your, gentle!");
28    }
29}

得到运行结果:

1Oh, boy!
2Hey, girl!
3Nice to meet your, gentle!
4Greetings, lady!

没毛病,对吧。

级联

现在,我们使用级联再来实现一次:

 1public class 级联 {
 2    public static void main(String[] args) {
 3        //实例化Guys
 4        Guys guys = new Guys();
 5        //执行方法
 6        guys.boy().girl().gentleman().lady();
 7    }
 8}
 9
10class Guys {
11    public Guys girl() {
12        System.out.println("Hey, girl!");
13        //把类再返回给你
14        return this;
15    }
16
17    public Guys boy() {
18        System.out.println("Oh, boy!");
19        return this;
20    }
21
22    public Guys lady() {
23        System.out.println("Greetings, lady!");
24        return this;
25    }
26
27    public Guys gentleman() {
28        System.out.println("Nice to meet your, gentle!");
29        return this;
30    }
31}

得到运行结果:

1Oh, boy!
2Hey, girl!
3Nice to meet your, gentle!
4Greetings, lady!

this

public Guys xxx() {

可以看到,我们每个方法都固定了返回值类型为Guys,即它的母类。

而在方法的最后:

return this;

this指向了它的母类Guys,所以当用户调用完以后,它就会再次返回一个Guys类,也就可以再次执行类中的方法了。

应用

感谢csfwff的补充:

级联调用也可以成为链式调用,在建造者模式(设计模式中的一种)中很常见。在我们要构建一个比较大的对象时,设定的值可能很多。通过链式调用,我们可以更有逻辑、方便地对其进行赋值。

使用建造者模式的伪代码:

1        Person person = new Person();
2        person.setName("CXK");
3        person.setAge("20");
4        person.setGender("男");
5        person.setCareer("唱跳Rap篮球");

使用链式调用(级联调用)后的伪代码:

1        Person person = new Person();
2        person.setName("CXK");
3              .setAge("20");
4              .setGender("男");
5              .setCareer("唱跳Rap篮球");

另外,经D大(@88250)指出,从更广义上来讲,也叫做平滑接口(FluentInterface):
https://martinfowler.com/bliki/FluentInterface.html

后语

某些场景中,可能需要多次调用同一个类中的方法,这时候级联调用就很好地保证了语句的连贯性和可读性,好极了。

但缺点也是比较明显的——执行后的值无法直接返回,因为它要返回它的母类。所以级联调用比较适用于不需要返回值的场景,或是设定一个静态的公共值(要注意线程安全问题,点我学习),在运行过程中进行修改。

如转载请在文章尾部添加

原作者来自 adlered 个人技术博客:https://www.stackoverflow.wiki/

    评论
    6 评论
    2019-07-19 11:17 回复»

    网上的相关资料也蛮少的。我的理解是把一些特定的级联调用方法封装好,组成了DSL供用户调用。期待有大佬解答

    2019-07-18 19:16 回复»

    那dsl是啥意思?

    2019-07-18 17:13 回复»

    感谢,我会订正的

    2019-07-18 17:12 回复»

    感谢指教,FluentInterface的概念要比我所说的"级联调用"更有深度一些,这就加以修改。

    2019-07-18 12:31 回复»

    更广义上叫做平滑接口。

    https://martinfowler.com/bliki/FluentInterface.html

    2019-07-18 12:00 回复»

    doge 链式调用,各种builder里很常见

avatar

取消