この記事では、java に関する関連知識を提供します。主にメソッド参照に関する関連問題を紹介します。メソッドは誰もが知っています。コードを記述するときに定義するメソッドです。メソッド参照は、このメソッドを参照するために使用されます。このリファレンス メソッドでは、ラムダ式をさらに最適化し、それによってコードの記述をより簡単にすることがその目的であることが明確になっています。
推奨学習: 「Java ビデオ チュートリアル 」
実際、私たちはそれを文字通りに理解し始めており、コードを書くときに定義するメソッドを誰もが知っています。メソッド参照は、このメソッドを参照するために使用されます。参照メソッドは、その目的がラムダ式をさらに最適化し、それによって記述されるコードを削減することであることを明確にしています。右!ラムダ式はすでに非常に最適化されていますが、どうすれば最適化できるのでしょうか?対応するクラス、オブジェクト、スーパー、および this がコード内に出現する場合、メソッド参照を使用できます。このメソッド参照の前提は、ラムダ式があることです。では、どのように使われるのでしょうか?引き続き下を見てみましょう。
タイトルがメソッド引用ということで、メソッド引用とは何でしょうか?メソッド参照演算子は ダブル コロン [::] で、これはメソッド参照であり、これはメソッド参照が実装される新しい構文である reference 演算子 でもあります。 。 Lambda によって表現される関数ソリューションがメソッドの実装にすでに存在する場合、二重コロンを使用してメソッドを参照し、Lambda を置き換えることができます。
注: Lambda に渡されるパラメータは、メソッド参照内のメソッドで受け入れられる型である必要があります。そうでない場合は、例外がスローされます。
メソッド参照は次のような方法で使用できます:
上記のような方法でメソッド参照があるので、一つ一つ勉強していきましょう。試してみてください。
では、オブジェクト名を介してメソッドを参照するにはどうすればよいでしょうか?オブジェクトはクラスを通じて作成されることがわかっているため、まずクラスを作成し、次にクラス内でメンバー メソッドを定義し、次にクラスを通じてオブジェクトを作成し、ペアを使用してメンバー メソッドを参照する必要があります。
例:
メンバーメソッドを定義し、文字列を渡し、その文字列を大文字で出力します
上記を記述します。要件を取り入れて実装しましょう。
最初にクラスを定義します
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); } }
スーパー記述は親クラスのメソッドに関連している、つまり継承関係があることが述べられています。継承関係があり、Lambda で super が呼び出される場合、代わりにメソッド参照が存在します。
会議メソッドを定義します
デモンストレーションのために子クラスと親クラスに集まって挨拶するメソッドを使用します
今回も同様に、会議メソッドを定義する 関数インターフェイス
/* 定义见面的函数式接口 */ @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(); } }
既然上面用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 中国語 Web サイトの他の関連記事を参照してください。