一.什么是行为参数化呢 说白了就是将一段行为当作参数传入一个方法中呗,那么这段行为是什么呢?

答:那也是一个方法咯。

Java在1.8版本引入了行为参数化的概念,首先,我们先看一小段代码

public class test { public static void main(String[] args){ Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };

    show(consumer ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 输出结果当然是:hello world 啦。

可是你想这有什么呢?不就是写了一个Consumer接口,然后写一个匿名类重写他的accept方法,然后带入Consumer到show方法调用它咩?Java没更新前也可以这样啊,只不过是传参了一个对象,然后在方法内调用了对象的方法。

那么我们再来看看下面这段代码,看看它和上面的代码有什么不同:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/

    show(System.out::println ,"hello world");
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 注意!代码中3到8行已经注释了哦。

现在看看:show方法接受一个Consumer对象和字符串,然后调用对象的accept方法,这里都没变;可是著方法中调用show方法的时候传递的第一个参数不再是Consumer对象了,而是System.out::println,而这是什么意思呢?

System.out::println 是方法引用,方法引用的格式就是:类名::方法名 或者 对象名::成员方法名

我们都知道,在方法重写和重载中我们是怎么做的呢?在子类中写一个和主类中被重写方法方法名相同、参数类型、顺序相同的方法,那jdk是根据什么来判断是否是重写或者重载呢?没错,就是靠函数签名来判断的,就比如上面代码中的show方法,它的函数签名就是:名为show、接受两个参数并且第一个参数是Consumer类型、第二个参数是String类型的函数,如果返回类型相同,则是重写;否则是重载。Java根据你的方法引用来确定你的方法签名和返回类型,如果和形参中Consumer对象中的方法相同的话,就可以使用。

那么我们回到代码中去,我们在主方法中调用show方法时传入的第一个参数就是一个:无返回值,接受一个泛型参数的方法签名的方法引用。

你也可以传入其他方法进去,只要方法签一致就可以啦。就像下面一样:

public class test { public static void main(String[] args){ /Consumer consumer = new Consumer() { @Override public void accept(String s) { System.out.println(s); } };/ test one = new test();

    show(one::otherMethod ,"hello world");
}public void otherMethod(T t){int i = 0;System.out.println(i + t.toString());
}public static void show(Consumer<String> consumer,String text){consumer.accept(text);
}
复制代码

} 结果是输出:0hello world

你也可以将show方法的第二个参数换成一个集合,然后在第一个参数中传入其他方法引用来对集合进行操作哦。

在上面我们说到在带哦用show方法时传入的方法引用的方法签名、返回类型要和Consumer对象中方法的一致,那么这个Consumer到底是什么呢?它的内部只有一个方法吗?如果有多个方法的话怎样根据传入的方法引用和他的众多方法比较呢?

答:Consumer其实是一个接口,一个函数式接口,话不多说,直接上源码

package java.util.function;

import java.util.Objects;

@FunctionalInterface public interface Consumer {

void accept(T t);default Consumer<T> andThen(Consumer<? super T> after) {Objects.requireNonNull(after);return (T t) -> { accept(t); after.accept(t); };
}
复制代码

} 大家看,是不是感觉有些不对呢?Java接口明明不能所有实现方法的,现在却多了一个default方法被实现,嘿嘿,这是Java8的新特性,这个我会在之后的帖子中继续和大家分享。大家要注意的是@FunctionalInterface这个注解,它表明这个接口是一个函数式接口,函数式接口的定义就是:一个有且只有一个抽象方法,但是可以有多个非抽象方法的接口。非抽象方法就是default方法,可以有多个,但是抽象方法只能有一个,那么上面关于传入方法引用怎样匹配方法签名和返回值的疑问你们理解了吗?

就是说在上面的例子中我在show方法定义的Consumer中只有一个抽象方法accept,他是一个无返回值,接受一个泛型参数的方法,而我在调用show方法的时候也传入了和accept方法返回值一致,参数相同的方法引用,这就是方法重写,在上面的例子中我传入System.out::println时就是无形之中创建了一个匿名类,然后重写了他的accept方法,重写的方法就是System.out.println()方法。神奇咩?嘿嘿...

等等,还没完...Consumer接口提供一个无返回值类型接受一个参数的抽象方法供大家使用,那么如果我有其他需求呢?假如我需要一个有返回值的抽象方法供我使用呢?

别急,Java提供了一系列函数式接口来供我们按照需求使用,如果没有自己需要的接口的话我们也可以自己写一个函数式接口来使用。

函数式接口 函数描述符 Predicate T->boolean Consumer T->void Function<T,R> T->R Supplier ()->T UnaryOperator T->T BinaryOperator (T,T)->T

BiPredicate<L,R> (L,R)->boolean BiConsumer<T,U> (T,U)->void BiFunction<T,U,R> (T,U)->R 函数描述符是什么呢?这就要说到Lambda表达式了,在下一篇博客中我会讲解。(本人是小白大学生一枚,如有不对或者不当之处,还请各位前辈指点,嘿嘿)

转载于:https://juejin.im/post/5c39af8a518825265c2fd86a

Java行为参数化(一)相关推荐

  1. java 行为参数化_Java中的行为参数化

    java 行为参数化 The past isn't here anymore, the future cannot be seen and the only thing permanent is th ...

  2. 浅谈Java行为参数化和Lambda表达式

    案例分析 在软件工程中,一个众所周知的问题就是,不管你做什么,用户的需求肯定会变.比方说,有个应用程序是帮助农民了解自己的库存的.这位农民可能想有一个查找库存中所有绿色苹果的功能.但到了第二天,他可能 ...

  3. java nextday_Nextday 参数化单元测试(测试用例)设计

    一.首先简单描述一下下载试题及配置试题的过程 配置环境:安装Eclipse.JDK(1.7).及考试插件 (net.mooctest....*.jar)等: 登录系统:运行Eclipse: [Mooc ...

  4. Java单元测试--参数化测试Parameterized的使用示例介绍

    在做单元测试时,可能同一个方法需要传很多个不同的参数进行测试,但是写一个测试参数写一个测试方法会比较冗余,那么有什么办法可以将一组参数进行测试吗?答案是有的. 使用 Parameterized,在测试 ...

  5. java mysql 参数化_JavaMySQL中like的参数化查询

    mysql使用参数化查询,like模糊查询,应如何拼接字符串 好奇是学习的源动力:因为在群里潜水看到关注sql注入的讨论,尝试在自己程序的搜索框输入单引号,程序报错,开始尝试修改为参数化查询,噩梦开始 ...

  6. parasoft Jtest 使用教程:创建并使用参数化测试用例(上)

    2019独角兽企业重金招聘Python工程师标准>>> 本次教程的内容是怎样生成和使用参数化的JUnit测试用例,一起来看看吧. parasoft Jtest介绍和试用>> ...

  7. java泛型面试_Java泛型面试问题

    java泛型面试 Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上. ...

  8. Java泛型面试问题

    Java面试中的通用面试问题在相当长的时间内在Java 5周围越来越普遍,许多应用程序都转移到Java 5上,并且几乎所有新的Java开发都发生在Tiger(Java 5的代号)上. 泛型和Java ...

  9. java构造函数_Java构造函数

    java构造函数 Constructor in java is used to create the instance of the class. Constructors are almost si ...

最新文章

  1. 商淘多b2b2c商城系统怎么在个人电脑上安装_B2B2c商城系统怎么选?开源和定制哪个好?...
  2. java传参怎么理解_如何理解Java的值传递
  3. opencv图像清晰度计算_Python中的十大图像处理工具
  4. 更改centos 7 的默认启动为命令界面
  5. blt功能_BitBlt实现TransparentBlt
  6. 最实用的18个HTML5 API 教程大全,都在这里了
  7. weex android app例子,weex中修改android app图标和欢迎页
  8. Web development mistakes
  9. vue 事件调用 传参_vue如何在父组件指定点击事件后向子组件传递参数并调用子组件的事件?...
  10. 不想打造物联网的制造型企业不是一家合格的百年老店
  11. TypeError: unhashable type: 'list'
  12. wikioi 1430 素数判定
  13. Maven系列--maven-compiler-plugin的使用、Maven之Surefire插件
  14. Linux下编译安装WizNote
  15. Unity游戏开发经验点滴
  16. CentOS 6 安装免费虚拟主机控制面板ZPanel
  17. 前端小白仿写小米官网首页(静态页面+jquery轮播图)
  18. python与环境统计学之f检验例题解答
  19. Android 3D画廊采用Gallery实现无限循环、自动轮播
  20. C++继承中的构造函数—计算圆柱体的表面积(函数名隐藏)

热门文章

  1. linux cpu使用率1200%,linux下用top命令查看cpu利用率超过100%
  2. Wampserver之 virtualHost
  3. Excel表格内容导出到页面
  4. bat-bat-bat (重要的事情说三遍)
  5. 2015/10/9 Python核编初级部分学习总结
  6. SWOT分析是神马?
  7. query上传插件uploadify参数详细分析
  8. winform错误提示 :窗口类名无效(Window class name is not valid)
  9. video from html5
  10. 后台设置 datakeynames