>  기사  >  Java  >  Java의 메소드 참조에 대한 심층 분석

Java의 메소드 참조에 대한 심층 분석

WBOY
WBOY앞으로
2022-06-13 17:55:192353검색

이 글은 java에 대한 관련 지식을 제공하며, 메소드 참조와 관련된 문제를 주로 소개합니다. 메소드는 우리가 코드를 작성할 때 정의하는 메소드입니다. 메서드 참조는 이 메서드를 참조하는 데 사용됩니다. 참조 방법은 람다 표현식을 더욱 최적화하여 코드를 더 간단하게 작성하는 것이 목적임을 분명히 합니다. 모든 사람에게 도움이 되기를 바랍니다.

Java의 메소드 참조에 대한 심층 분석

추천 학습: "java 비디오 튜토리얼"

메소드 참조란 무엇인가요? ㅋㅋㅋ                                                                                          사실 우리는 코드를 작성할 때 정의하는 메소드를 문자 그대로 이해하기 시작합니다. 메서드 참조는 이 메서드를 참조하는 데 사용됩니다. 참조 방법은 람다 표현식을 더욱 최적화하여 코드 작성을 더 간단하게 줄이는 것이 목적임을 분명히 합니다. 오른쪽! 맞습니다. 람다 표현식은 이미 매우 최적화되어 있는데 어떻게 최적화할 수 있습니까? 해당 클래스, 객체, super 및 this가 코드에 나타나면 메서드 참조를 사용할 수 있습니다. 이 메서드 참조의 전제는 Lambda 표현식이 있다는 것입니다. 그럼 어떻게 사용되나요? 계속해서 아래를 살펴보겠습니다.

방법인용

제목이 방법인용인데 방법인용이란 무엇인가요? 메소드 참조 연산자는 메소드 참조인

이중 콜론 [::]

이며, 이것도 새로운 구문인 참조 연산자이며, 이를 통해 메소드 참조가 구현됩니다. Lambda가 표현하려는 함수 솔루션이 메소드 구현에 이미 존재하는 경우 이중 콜론을 사용하여 Lambda를 대체하는 메소드를 참조할 수 있습니다.

참고: Lambda에 전달된 매개 변수는 메서드 참조의 메서드에서 허용되는 유형이어야 합니다. 그렇지 않으면 예외가 발생합니다.

메서드 참조를 사용하는 방법은 무엇입니까?

메소드 참조는 다음과 같은 방법으로 사용할 수 있습니다.

Java의 메소드 참조에 대한 심층 분석 위의 방법에도 메소드 참조가 있으므로 하나씩 살펴보겠습니다.

객체 이름을 통한 멤버 메소드 참조

                                                                ~ 우리는 객체가 클래스를 통해 생성된다는 것을 알고 있으므로 먼저 클래스를 생성한 다음 클래스에 멤버 메서드를 정의한 다음 클래스를 통해 객체를 생성하고 쌍을 사용하여 멤버 메서드를 참조해야 합니다.

예:

멤버 메소드를 정의하고 문자열을 전달한 후 문자열을 대문자로 출력합니다.

위 요구 사항을 구현해 보겠습니다.

먼저 클래스를 정의

public class Demo02MethodRerObject {

//定义一个成员方法,传递字符串,把字符串按照大写输出

public void printUpperCaseString(String s){

System.out.println(s.toUpperCase());

}

}

출력이기 때문에 출력해야 하는데, Lambdab를 사용하려면 인쇄를 위한 함수형 인터페이스를 정의해야 하고, 함수형 인터페이스에서 문자열을 인쇄하는 추상 메서드를 정의해야 합니다.

/*

定义一个打印的函数式接口

*/

@FunctionalInterface

public interface Printable {

//定义打印字符串的抽象方法

void print(String s);

}
对는 객체 이름을 통해 멤버 메소드를 인용할 수 있습니다. 전제는 객체 이름이 존재하고, 멤버 메소드도 존재한다는 것입니다. 코드로 작성해 보겠습니다. 먼저 Lambda를 사용하여 이 요구 사항을 작성한 다음 메서드 참조를 사용하여 Lambda를 최적화합니다.

public class Demo03ObjectMethodReference {

//定义一个方法,方法参数传递Printable接口

public static void pringString(Printable p){

p.print("abcde");

}

public static void main(String[] args) {

//pringString(System.out::print);

//调用printString方法,方法的参数pringable是一个函数式接口,所以可以传递Lambda

pringString((s)->{

//创建MethodRerObject对象

Demo02MethodRerObject methodRerObject=new Demo02MethodRerObject();

//调用Demo02MethodRerObject对象中的成员方法printUpperCaseString,把字符串按照大写输出

methodRerObject.printUpperCaseString(s);

});

/*

使用方法引用优化Lambda

对象已经存在Demo02MethodRerObject

成员方法也是已经存在的printUpperCaseString

所以我们可以使用对象名引用成员方法

*/

Demo02MethodRerObject methodRerObject=new Demo02MethodRerObject();

pringString(methodRerObject::printUpperCaseString);

}

}
클래스 이름을 통해 정적 메서드 참조

앞서 배운 클래스에 정적 메서드가 있으면 클래스 이름을 통해 정적 메서드를 호출할 수 있으며 메서드 참조도 마찬가지입니다. 클래스 이름을 통한 정적 메소드. 아래에서는 코드를 사용하여 시연합니다.

이번에는 메소드를 정의합니다.

메서드의 매개변수는 정수의 절대값을 계산하기 위해 전달되고 함수형 인터페이스 Calcable
입니다.

먼저 인터페이스를 정의하세요

@FunctionalInterface

public interface Calcable {

//定义一个抽象方法,传递一个整数,对整数进行绝对值计算并返回

int AbsCals(int number);

}
​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ 전제는 클래스가 이미 존재하고 정적 멤버 메서드가 이미 존재한다는 것입니다. 클래스 이름을 사용하여 정적 멤버 메서드를 직접 참조할 수 있습니다. 또한 먼저 클래스를 생성하고, 메서드를 정의하고, Lambda로 코드를 작성한 다음 메서드 참조 최적화를 사용합니다.

public class Demo04StaticMethodReference {

//定义一个方法,方法的参数传递计算绝对值的整数和函数式接口Calcable

public static int method1(int number,Calcable c){

return c.AbsCals(number);

}

public static void main(String[] args) {

//调用method方法,传递计算绝对值的整数和lambda表达式

int number=method1(-10,(n)->{

//对参数进行绝对值计算并返回结果

return Math.abs(n);

});

System.out.println(number);

/*

使用方法引用优化Lambdab表达式

Math类是存在的

abs计算绝对值的静态方法也是存在的

所以我们可以直接通过类名引用静态方法

*/

int number2=method1(-10, Math::abs);

System.out.println(number2);

}

}
u를 통해 멤버 메소드 인용

Super 설명이 상위 메소드, 즉 상속과 관련이 있다고 언급했습니다. 상속 관계가 있고 super가 Lambda에서 호출되면 대신 메서드 참조가 있습니다.

회의 방법 정의

시연을 위해 하위 클래스와 상위 클래스 간의 만남과 인사의 방법을 사용합니다또한 이번에는 회의의 기능적 인터페이스를 정의합니다

/*

定义见面的函数式接口

*/

@FunctionalInterface

public interface Greetable {

//定义一个见面的方法

void greet();

}

상속해야 하므로 학부모 수업

/*

定义父类方法

*/

public class Demo05Fu_Human {

//定义一个sayHello的方法

public void sayHello(){

System.out.println("Hello! 我是Human。");

}

}

        再定义一个子类,在子类中出现父类的成员方法,先使用Lambda编写代码,再进行方法引用优化。

        使用super引用父类的成员方法,前提super是已经存在的,父类的成员方法也是存在的,就可以直接使用super引用父类成员方法。

import java.nio.channels.ShutdownChannelGroupException;

/*

定义子类

*/

public class Demo06Zi_Man extends Demo05Fu_Human {

//子类重写父类sayHello方法

@Override

public void sayHello() {

System.out.println("Hello!我是Man。");

}

//定义一个方法,参数传递Gerrtable接口

public void method(Greetable g){

g.greet();

}

public void show(){

//调用method方法,方法参数Greetable是一个函数式接口,所以可以传递Lambda表达式

method(()->{

//创建父类的Human对象

Demo05Fu_Human fHuman=new Demo05Fu_Human();

fHuman.sayHello();

});

//因为有子父类关系,所以存在的一个关键super,代表父类,可以直接使用super调用父类的成员方法

method(()->{

super.sayHello();

});

/*

使用super引用类的成员方法

super是已经存在的

父类的成员方法也是存在的

使用可以直接使用super引用父类成员方法

*/

method(super::sayHello);

}

public static void main(String[] args) {

//调用show方法

new Demo06Zi_Man().show();

}

}

通过this引用成员方法

        既然上面用super引用了父类的成员方法,我们之前也学过this也可以调用本类的成员方法,那同样this也可以引用本类的成员方法。

示例:

定义一个买房子的方法

同样,首先定义函数式接口。

/*

定义一个富有的函数式接口

*/

@FunctionalInterface

public interface Richable {

//定义一个想买什么就买什么的方法

void buy();

}

        然后怎么创建类,再定义买房子的方法。通过this引用成员方法,前提this是已经存在的,买房子的成员方法也是存在的,就可以直接使用this引用成员方法。同样先使用Lambda编写代码,再进行方法引用优化。

/*

通过this引用本类的成员方法

*/

public class Demo07_Husband {

//定义一个买房子的方法

public void buyHouse(){

System.out.println("北京二环内买一套四合院!");

}

//定义一个结婚的方法,参数传递Richable接口

public void marry(Richable r){

r.buy();

}

//定义一个高兴的方法

public void soHappy(){

//调用结婚的方法,方法的参数Richable是一个函数式接口,传递Lambda表达式

marry(()->{

//使用this,成员方法,调用本类买房子的方法

this.buyHouse();

});

/*

使用方法引用优化Lambda

this是已经存在的

买房子的成员方法也是存在的

可以直接使用this引用成员方法

*/

marry(this::buyHouse);

}

public static void main(String[] args) {

new Demo07_Husband().soHappy();

}

}

类的构造器引用

        类的构造器引用也叫构造方法引用。而由于构造器名称和类名完全一样,所以构造器引用格式是这样的,类名称::new的格式表示。既然是构造器引用也就是构造方法引用,所以我们需要:

定义一个Person类。

/*

person类

*/

public class Person {

private String name;

public Person() {

super();

// TODO Auto-generated constructor stub

}

public Person(String name) {

super();

this.name = name;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

然后创建一个Person对象的函数式接口

*

定义一个创建erson对象的函数式接口

*/

@FunctionalInterface

public interface PersonBuilder {

//定义一个方法,根据传递的姓名,创建person对象返回

Person buliderPerson(String name);

}

        再传递一个方法,参数传递姓名和PersonBulider接口,方法中通过 姓名创建Person对象。类的构造器引用,前提构造方法new Person(String name)已知,创建对象已知 new,就可以使用Person引用new创建对象。同样先使用Lambda编写代码,再进行方法引用优化。

/*

类的构造器(构造方法)引用

*/

import java.time.chrono.MinguoChronology;

import javax.print.attribute.standard.PrinterName;

public class Demo08Person {

//传递一个方法,参数传递姓名和PersonBulider接口,方法中通过 姓名创建Person对象

public static void printName(String name,PersonBuilder pb){

Person person=pb.buliderPerson(name);

System.out.println(person.getName());

}

public static void main(String[] args) {

//调用printName方法,方法的参数传递了函数式接口,我们可以使用Lambda表达式

printName("张三",(name)->{

return new Person(name);

});

/*使用方法引用优化Lambda表达式

构造方法new Person(String name)已知

创建对象已知 new

就可以使用Person引用new创建对象*/

printName("痛而不言笑而不语的浅伤",Person::new);

}

}

数组的构造器引用

        数组也是Object的子类,所以它也有方法引用,只是语法上稍有不同。

示例:

定义一个方法

方法的参数传递创建数组的长度和ArrayBulider接口

方法内部根据创建的长度使用ArrayBuilder中的方法创建数组并返回

同样,先创建一个数组的函数式接口

/*

定义一个创建数组的函数式接口

*/

@FunctionalInterface

public interface ArrayBulider {

// 定义一个int类型的数组方法,参数传递数组的长度,返回创建好的int类型的数组

int[] buliderArray(int length);

}

        方法的参数传递创建数组的长度和ArrayBulider接口,方法内部根据创建的长度使用ArrayBuilder中的方法创建数组并返回。前提,已知创建的就是int[]数组,数组的长度也是已知的,就可以通过数组int[]引用new,根据参数传递的长度来创建数组同样先使用Lambda编写代码,再进行方法引用优化。

import java.lang.reflect.Array;

import java.util.Arrays;

/*

数组的构造器引用

*/

public class Demo09Array_BuilderArray {

/*
定义一个方法

方法的参数传递创建数组的长度和ArrayBulider接口

方法内部根据创建的长度使用ArrayBuilder中的方法创建数组并返回

*/

public static int[] arrayLength(int length,ArrayBulider ab){

return ab.buliderArray(length);

}

public static void main(String[] args) {

//调用arrayLength方法、传递数组的长度和Lambda表达式

int[]arr=arrayLength(10,(len)->{

return new int[len];

});

System.out.println(arr.length);

/*使用方法引用优化Lambda表达式

已知创建的就是int[]数组

数组的长度也是已知的

就可以通过数组int[]引用new,根据参数传递的长度来创建数组*/

int[]arr1=arrayLength(5, int[]::new);

System.out.println(arr1.length);

System.out.println(Arrays.toString(arr1));

}

}

推荐学习:《java视频教程

위 내용은 Java의 메소드 참조에 대한 심층 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제