Java中双冒号: :的作用

这篇具有很好参考价值的文章主要介绍了Java中双冒号: :的作用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、定义

双冒号运算操作符是类方法的句柄,lambda表达式的一种简写

表达式:
person -> person.getName();
可以替换成:
Person::getName

表达式:
() -> new HashMap<>();
可以替换成:
HashMap::new

二、如何理解

双冒号(::)运算符在Java 8中被用作方法引用(method reference),方法引用是与lambda表达式相关的一个重要特性。它提供了一种执行方法的方法,为此,方法引用需要由兼容的函数式接口组成的目标类型上下文。使用lambda表达式会创建匿名函数, 但有时候需要使用一个lambda表达式只调用一个已经存在的方法(不做其它), 所以这才有了方法引用!

其实,JVM 本身并不支持指向方法引用,过去不支持,现在也不支持。Java 8 对方法引用的支持只是编译器层面的支持,虚拟机执行引擎并不了解方法引用。编译器遇到方法引用的时候,会像上面那样自动推断出开发者的意图,将方法引用还原成接口实现对象,或者更形象地说,就是把方法引用设法包装成一个接口实现对象,这样虚拟机就可以无差别地执行字节码文件而不需要管什么是方法引用了。

需要注意的是,方法引用是用来简化接口实现代码的,并且凡是能够用方法引用来简化的接口,都有这样的特征:有且只有一个待实现的方法。这种接口在 Java 中有个专门的名称: 函数式接口。当试图用方法引用替代一个非函数式接口时,会有这样的错误提示: xxx is not a functional interface。

三、使用场景

类型

引用语法

案例

引用静态方法

类名::静态方法名

Integer::parseInt

引用特定对象实例方法

对象::实例方法名

System.out::println

引用特定类型的任意对象的实例方法

特定类型::实例方法名

String::compareToIgnoreCase

引用超类(父类)实例方法

super::方法名

引用类构造方法

类名::new

ArrayList::new

引用数组构造方法

数组类型[]::new

String[]::new

案例详解:

  1. 引用静态方法

import org.junit.Test;
import java.util.Arrays;
import java.util.List;

public class Colon{
@Test
    public void test(){
        List<String> list = Arrays.asList("a", "b","c");
        //静态方法引用ClassName::methodName
        list.forEach(Colon:: print);
        //上一行等价于
        //1ist.forEach((x)->Colon.print(x));
    }
    //静态方法
    public static void print(String s){
        system.out.println(s);
    }
}
  1. 引用特定对象实例方法

import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class Colon{
    @Test
    public void test(){
        List<string> list = Arrays.asList("a", "b","c");//r实例方法引用instanceRef: :methodName
        list.forEach(new Colon()::print);
        //上一行等价于
        //iist.forEach((x)->new Colon().print(x));
    }
    //实例方法
    public void print(String s){
        System.out.println(s);
    }
}
  1. 引用特定类型的任意对象的实例方法

import org.junit.Test;
import java.util.Arrays;

public class Colon{
    @Test
    public void test(){
        String[] arr = { "Barbara","James","Mary", "John",
                "Patricia","Robert","Michae1", "Linda”};
        //引用String类型的任意对象的compareToIgnoreCase方法实现忽略大小写排序
        Arrays.sort(arr, String::compareToIgnoreCase);
        //上一行等价于
        //Arrays.sort(arr, (a,b)->a.compareToIgnoreCase(b));
        //输出
        for(String s:arr){
            System.out.println(s);
        }
}
  1. 引用超类(父类)实例方法

import org.junit.Test;
import java.util.Arrays;
import java.util.List;

public class Colon extends BaseColon{
    @Test
    public void test(){
        List<string> list = Arrays.asList("a", "b","c");
        //实例方法引用instanceRef::methodName
        list.forEach(super:: print);
    }
}
class Basecolon{
    //实例方法
    public void print(string s){
        System.out.println(s);
    }
}
  1. 引用类构造方法

一般我们需要声明接口,该接口作为对象的生成器,通过 类名::new 的方式来实例化对象,然后调用方法返回对象。

//注意:该类无需实现接口
public class Colon{
    private String name;
    private int age;
    //无参构造
    public Colon(){ }
    //有参构造
    public colon(String name, int age){
        this.name = name;
        this.age = age;
    }
    public static void main(String[] args){
        //无参构造引用
        ColonNoParam cnp = Colon::new;
        colon c1 = cnp.createColon();
        System.out.println(c1);
        //有参构造引用
        ColonlithParam cwp = Colon::new;
        colon c2 = cwp.createColon("小明",20);
        System.out.println(c2);
    }
    //生成toString方法打印查看
    @Override
    public string toString() {
        return "Colon{" +
                "name='"+ name + "\"+
                ",age=" + age +
                '}';
    }
}
interface colonNoParam{
    //无参方法提供对象
    Colon createColon();
}
interface ColonwithParam{
    //有参方法提供对象(数据类型要与colon有参构造函数对应)
    colon createColon(String s,int i);
}
  1. 引用数组构造方法

我们可以借助jdk自带的java.util.function.Function类实现对数组构造函数的引用。​​​​​​​

当然,我们也可以使用@FunctionalInterface自定义函数式接口来实现:

public class Colon{
    public static void main(string[] args) {
        MyArrayFunction<Integer,Colon[]> function = Colon[]::new;
        //调用apply方法创建数组,这里的5是教组的长度
        colon[] arr = function.apply(5);
        //循环输出-初始都为null
        for(Colon c:arr){
            System.out.println(c);
        }
    }
}
//自定义函教式接口
@FunctionalInterface
interface MyArrayFunction<A,T>{
    T apply(A a);
}

参考博客:https://blog.csdn.net/yangzhe19931117/article/details/128246653文章来源地址https://www.toymoban.com/news/detail-729412.html

到了这里,关于Java中双冒号: :的作用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA基础JVM讲解

      主要包括两个子系统和两个组件: Class loader(类装载器) 子系统(用来装载.class文件); Execution engine(执行引擎) 子系统(执行字节码,或者执行本地方法); Runtime data area (运行时数据区域)组件(方法区、堆、java栈、PC寄存器、本地方法栈); Native interface(本地接口)组件。

    2024年02月07日
    浏览(47)
  • 3.Java面试题—JVM基础、内存管理、垃圾回收、JVM 调优

    一篇文章掌握整个JVM,JVM超详细解析!!! JVM (Java虚拟机) 是运行 Java 字节码 的 虚拟机 。 JVM 针对 不同系统 有 特定实现 ( Windows 、 Linux 等),目的是 同样的代码 在 不同平台 能运行出 相同的结果 。 Java 语言 要经过 编译 和 解释 两个步骤: 编译 :通过 编译器 将 代码 一

    2024年02月15日
    浏览(50)
  • (C#) IIS 响应标头过滤敏感信息(如:Server/X-Powered-By等) 运维知识

    再一次净网行动中,客户要求安全改造发现了接口请求的header标头中出现如图中的敏感信息。   其意义在于告知浏网站是用什么语言或者框架编写的。解决办法就是修改该响应头为一个错误的值,将攻击者导向一个错误的方向。 这里只说windows 的iis环境,不考虑其他服务器的

    2024年02月11日
    浏览(73)
  • 【Java基础】- JVM之Dump文件详解

    学习Jvm调优,我们会接触到Dump文件。什么是Dump文件、Dump文件是如何得到的。当程序崩溃时,如何从Dump文件还原崩溃时的信息。本文讲重点讲解。 Thread Dump是非常有用的诊断Java应用问题的工具。每一个Java虚拟机都有及时生成所有线程在某一个点状态的thread-dump的能力,虽然

    2024年02月13日
    浏览(41)
  • 【java八股文】之JVM基础篇

    【java八股文】之JVM基础篇-CSDN博客 【java八股文】之MYSQL基础篇-CSDN博客 【java八股文】之Redis基础篇-CSDN博客 【java八股文】之Spring系列篇-CSDN博客 【java八股文】之分布式系列篇-CSDN博客 【java八股文】之多线程篇-CSDN博客 【java八股文】之JVM基础篇-CSDN博客 【java八股文】之计算

    2024年01月17日
    浏览(39)
  • 【JAVA基础】JVM之类加载--双亲委派机制

    1. 类加载的过程 描述: 我们写的 .java 文件通过编译成字节码文件 .class 文件,然后再通过我们的类加载器:Class Loader,反射以后,类模板存在方法区,把实例化的对象存在堆里; 看图: 对象的hashcode值 解释: 从图中我们可以看出,从同一个类模板new出来三个对象(实例化

    2024年01月23日
    浏览(45)
  • Java基础常考知识点(基础、集合、异常、JVM)

    作者: 逍遥Sean 简介:一个主修Java的Web网站游戏服务器后端开发者 主页:https://blog.csdn.net/Ureliable 觉得博主文章不错的话,可以三连支持一下~ 如有需要我的支持,请私信或评论留言! 本文收集Java核心的面试常考知识点,码起面试之前复习!!! JDK(Java SE Development Kit) ,

    2024年02月07日
    浏览(57)
  • JAVA后端开发面试基础知识(一)——JVM

    Class loader(类装载) 根据给定的全限定名类名(如: java.lang.Object)来装载class文件到 Runtime data area中的method area。 Execution engine(执行引擎) 执行classes中的指令。 Native Interface(本地接口) 与native libraries交互,是其它编程语言交互的接口。 Runtime data area(运行时数据区域) 这就是我们常说

    2024年03月10日
    浏览(60)
  • 【java基础面试题】jdk、jre、jvm区别

    【java基础面试题】jdk、jre、jvm区别 jdk ​ 从概念上讲JDK是JAVA开发工具,用它来开发JAVA程序,里面有很多基础类库和jre。 ​ JDK(Java Development Kit),它是功能齐全的 Java SDK,是提供给开发者使用的,能够创建和编译 Java 程序。他包含了 JRE,同时还包含了编译 java 源码的编译器

    2024年02月10日
    浏览(47)
  • JVM零基础到高级实战之Java内存区域本地方法栈

    JVM零基础到高级实战之Java内存区域本地方法栈 JVM零基础到高级实战之Java内存区域本地方法栈 本地方法栈是什么? 用于作用域本地方法执行的一块Java内存区域 为什么要有本地方法栈? 与Java虚拟机栈相同,每个方法在执行的同时都会创建一个栈帧(Stack Framel)用于存储局部

    2024年02月09日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包