{"id":311302,"date":"2020-10-12T09:00:15","date_gmt":"2020-10-12T09:00:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=311302"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2020-10-12T09:00:15","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=311302","title":{"rendered":"\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 Method \u0438\u0437 Method Reference \u0432 Java"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/522774\/\">\n<p>\u042f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u2014 \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 method reference \u0432\u0438\u0434\u0430<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">Function&lt;String, Integer&gt; fun = String::length;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 (\u0438\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u0435\u0433\u043e \u0438\u043c\u044f), \u0442.\u0435. \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e <code>java.lang.String.length()<\/code>. \u041a\u0430\u043a \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u043d\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044f \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u043b \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u043d\u0430\u0448\u043b\u0438\u0441\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0430 stackoverflow <a href=\"https:\/\/stackoverflow.com\/questions\/19845213\" rel=\"nofollow\">[1]<\/a>, <a href=\"https:\/\/stackoverflow.com\/questions\/21860875\" rel=\"nofollow\">[2]<\/a>, \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 GitHub, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u043a\u0430\u0441\u0430\u044e\u0442\u0441\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b <a href=\"https:\/\/github.com\/cronn-de\/reflection-util\" rel=\"nofollow\">[1]<\/a>, <a href=\"https:\/\/github.com\/jhalterman\/typetools\" rel=\"nofollow\">[2]<\/a>, <a href=\"https:\/\/github.com\/Hervian\/safety-mirror\" rel=\"nofollow\">[3]<\/a>, \u043d\u043e \u043d\u0435 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043d\u0435 \u0434\u0430\u0435\u0442 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435 <a href=\"https:\/\/habr.com\/ru\/users\/ibessonov\/\" class=\"user_link\">ibessonov<\/a> \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b <a href=\"https:\/\/habr.com\/ru\/post\/311788\/\">\u0441\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/a>, \u0430 <a href=\"https:\/\/habr.com\/ru\/users\/apangin\/\" class=\"user_link\">apangin<\/a> \u2014 \u0441\u0432\u043e\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/311788\/#comment_9843134\">\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438<\/a>. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0410\u043d\u0434\u0440\u0435\u044f \u043c\u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f, \u043d\u043e \u0432\u0441\u043a\u043e\u0440\u0435 \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 JDK, \u0432\u0441\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 Java 8, \u043d\u043e \u043d\u0435 \u0432 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0437\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0440\u044f\u0434 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f <code>BiFunction<\/code> \u0438\u043b\u0438 <code>BiConsumer<\/code> \u043e\u043d \u0432\u044b\u0434\u0430\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u044d\u0442\u043e \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445).<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u044d\u0442\u0438\u0445 \u0438\u0437\u044c\u044f\u043d\u043e\u0432 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043f\u043e\u0437\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 JDK \u2014 SerializedLambda. \u0417\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0435\u0434 \u0441\u0440\u0430\u0437\u0443 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0430\u043a <code>java.io.Serializable<\/code> (\u0442.\u0435. \u0441 <code>java.util.function.Function<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442), \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"zachem-voobsche-eto-nuzhno\">\u0417\u0430\u0447\u0435\u043c \u0432\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e?<\/h2>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0440\u0435\u0448\u0435\u043d\u0438\u044e, \u043e\u0442\u0432\u0435\u0447\u0443 \u043d\u0430 \u0440\u0435\u0437\u043e\u043d\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441 \u0430 \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f?<br \/>  \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u043b\u0441\u044f \u0447\u0435\u0440\u0435\u0437 method reference. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b\u0439 \u0438 compile-\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439 \u043a\u043e\u0434. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c <a href=\"https:\/\/github.com\/seregamorph\/hamcrest-more-matchers\/blob\/master\/readme.md\" rel=\"nofollow\">&quot;where&quot;<\/a> hamcrest matcher, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u044e-extractor \u0434\u043b\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">List&lt;SamplePojo&gt; list = Arrays.asList(         new SamplePojo()                 .setName(&quot;name1&quot;),         new SamplePojo()                 .setName(&quot;name2&quot;) );  \/\/ success assertThat(list, hasItem(where(SamplePojo::getName, equalTo(&quot;name1&quot;)))); \/\/ fails with diagnostics: \/\/ java.lang.AssertionError:  \/\/ Expected: every item is Object that matches &quot;name1&quot; after call SamplePojo.getName \/\/     but: an item was &quot;name2&quot; assertThat(list, everyItem(where(SamplePojo::getName, equalTo(&quot;name1&quot;))));<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u0442\u0435\u0441\u0442 \u0443\u043f\u0430\u0434\u0435\u0442 \u0441 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u043e\u0439 <strong><code>&quot;after call SamplePojo.getName&quot;<\/code><\/strong>. \u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0430 \u044d\u0442\u043e \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u043c, \u043d\u043e hamcrest-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0443\u044e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043b\u0438\u0448\u043d\u044f\u044f \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u043e\u043c\u0435\u0448\u0430\u0435\u0442.<\/p>\n<p>  <\/p>\n<h2 id=\"serializedlambda\">SerializedLambda<\/h2>\n<p>  <\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 <a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/api\/java\/lang\/invoke\/SerializedLambda.html\" rel=\"nofollow\">java.lang.invoke.SerializedLambda<\/a> \u2014 \u044d\u0442\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412\u0430\u0436\u043d\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u043e\u043c\u0435\u0447\u0435\u043d \u043a\u0430\u043a <code>Serializable<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@FunctionalInterface public interface ThrowingFunction&lt;T, R&gt; extends java.io.Serializable {     R apply(T t) throws Exception; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437 javadoc \u043a\u043b\u0430\u0441\u0441\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 <code>SerializedLambda<\/code>, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 <code>writeReplace<\/code> \u043d\u0430 \u043b\u044f\u043c\u0431\u0434\u0430-\u043e\u0431\u044a\u0435\u043a\u0442\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@Nullable private static SerializedLambda getSerializedLambda(Serializable lambda) {     for (Class&lt;?&gt; cl = lambda.getClass(); cl != null; cl = cl.getSuperclass()) {         try {             Method m = cl.getDeclaredMethod(&quot;writeReplace&quot;);             m.setAccessible(true);             Object replacement = m.invoke(lambda);             if (!(replacement instanceof SerializedLambda)) {                 break;             }             return (SerializedLambda) replacement;         } catch (NoSuchMethodException e) {             \/\/ skip, continue         } catch (IllegalAccessException | InvocationTargetException | SecurityException e) {             throw new IllegalStateException(&quot;Failed to call writeReplace&quot;, e);         }     }     return null; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0434\u043e\u0441\u0442\u0430\u0435\u043c \u0438\u0437 <code>SerializedLambda<\/code>, \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043c\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0447\u0435\u0440\u0435\u0437 <code>&quot;\/&quot;<\/code>(\u0441\u043b\u0435\u0448) \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0447\u0435\u043a, \u0430 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>getImplMethodSignature()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 <code>&quot;(Z)V&quot;<\/code>, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 (\u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u043a\u043e\u0431\u043e\u043a) \u0442\u0438\u043f\u0430 <code>boolean<\/code> (<code>&quot;Z&quot;<\/code>), \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u2014 <code>void<\/code> (<code>&quot;V&quot;<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">static Class&lt;?&gt;[] parseArgumentClasses(String implMethodSignature) {     int parenthesesPos = implMethodSignature.indexOf(')');     if (!implMethodSignature.startsWith(&quot;(&quot;) || parenthesesPos &lt;= 0) {         throw new IllegalStateException(&quot;Wrong format of implMethodSignature &quot; + implMethodSignature);     }     String argGroup = implMethodSignature.substring(1, parenthesesPos);     List&lt;Class&lt;?&gt;&gt; classes = new ArrayList&lt;&gt;();     for (String token : argGroup.split(&quot;;&quot;)) {         if (token.isEmpty()) {             continue;         }         classes.add(parseType(token, false));     }     return classes.toArray(new Class[0]); }  private static Class&lt;?&gt; parseType(String typeName, boolean allowVoid) {     if (&quot;Z&quot;.equals(typeName)) {         return boolean.class;     } else if (&quot;B&quot;.equals(typeName)) {         return byte.class;     } else if (&quot;C&quot;.equals(typeName)) {         return char.class;     } else if (&quot;S&quot;.equals(typeName)) {         return short.class;     } else if (&quot;I&quot;.equals(typeName)) {         return int.class;     } else if (&quot;J&quot;.equals(typeName)) {         return long.class;     } else if (&quot;F&quot;.equals(typeName)) {         return float.class;     } else if (&quot;D&quot;.equals(typeName)) {         return double.class;     } else if (&quot;V&quot;.equals(typeName)) {         if (allowVoid) {             return void.class;         } else {             throw new IllegalStateException(&quot;void (V) type is not allowed&quot;);         }     } else {         if (!typeName.startsWith(&quot;L&quot;)) {             throw new IllegalStateException(&quot;Wrong format of argument type &quot;                     + &quot;(should start with 'L'): &quot; + typeName);         }         String implClassName = typeName.substring(1);         return implClassForName(implClassName);     } }  private static Class&lt;?&gt; implClassForName(String implClassName) {     String className = implClassName.replace('\/', '.');     try {         return Class.forName(className);     } catch (ClassNotFoundException e) {         throw new IllegalStateException(&quot;Failed to load class &quot; + implClassName, e);     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@Nullable public static Method unreferenceLambdaMethod(Serializable lambda) {     SerializedLambda serializedLambda = getSerializedLambda(lambda);     if (serializedLambda != null             &amp;&amp; (serializedLambda.getImplMethodKind() == MethodHandleInfo.REF_invokeVirtual             || serializedLambda.getImplMethodKind() == MethodHandleInfo.REF_invokeStatic)) {         Class&lt;?&gt; cls = implClassForName(serializedLambda.getImplClass());         Class&lt;?&gt;[] argumentClasses = parseArgumentClasses(serializedLambda.getImplMethodSignature());         return Stream.of(cls.getDeclaredMethods())                 .filter(method -&gt; method.getName().equals(serializedLambda.getImplMethodName())                         &amp;&amp; Arrays.equals(method.getParameterTypes(), argumentClasses))                 .findFirst().orElse(null);     }     return null; }<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"a-s-konstruktorami-rabotaet\">\u0410 \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442?<\/h2>\n<p>  <\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u0442\u0438\u043f <code>serializedLambda.getImplMethodKind()<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@Nullable public static Constructor&lt;?&gt; unreferenceLambdaConstructor(Serializable lambda) {     SerializedLambda serializedLambda = getSerializedLambda(lambda);     if (serializedLambda != null             &amp;&amp; (serializedLambda.getImplMethodKind() == MethodHandleInfo.REF_newInvokeSpecial)) {         Class&lt;?&gt; cls = implClassForName(serializedLambda.getImplClass());         Class&lt;?&gt;[] argumentClasses = parseArgumentClasses(serializedLambda.getImplMethodSignature());         return Stream.of(cls.getDeclaredConstructors())                 .filter(constructor -&gt; Arrays.equals(constructor.getParameterTypes(), argumentClasses))                 .findFirst().orElse(null);     }     return null; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">\/\/ new Integer(String) ThrowingFunction&lt;String, Integer&gt; fun = Integer::new;  Constructor&lt;?&gt; constructor = unreferenceLambdaConstructor(fun);<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"sovmestimost\">\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c<\/h2>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 Java 8, Java 11, Java 14, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438\u043b\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u043c api JDK, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 JVM. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u043e \u0438 \u043a \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0438 \u043a \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u0441 \u0440\u0430\u0437\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u0442.\u0435. \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e Function-\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0435).<br \/>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043d\u0435\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u2014 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u0438\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u043c\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">@FunctionalInterface public interface SerializableBiFunction&lt;T, U, R&gt; extends Serializable {     R apply(T arg1, U arg2); }  \/\/ Integer.parseInt(String, int) SerializableBiFunction&lt;String, Integer, Integer&gt; fun = Integer::parseInt;  Method method = unreferenceLambdaMethod(fun);<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/seregamorph\/hamcrest-more-matchers\/blob\/master\/src\/main\/java\/com\/github\/seregamorph\/hamcrest\/TestLambdaUtils.java#L35\" rel=\"nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"gotovyy-utilitarnyy-metod\">\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u0430\u0440\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434<\/h2>\n<p>  <\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/github.com\/seregamorph\/hamcrest-more-matchers\/blob\/master\/src\/main\/java\/com\/github\/seregamorph\/hamcrest\/TestLambdaUtils.java\" rel=\"nofollow\">\u043a\u043b\u0430\u0441\u0441<\/a> \u0432 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043d\u043e \u044f \u0431\u044b \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0432\u043d\u0435 scope test. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c:<\/p>\n<p>  <\/p>\n<pre><code class=\"xml\">&lt;dependency&gt;     &lt;groupId&gt;com.github.seregamorph&lt;\/groupId&gt;     &lt;artifactId&gt;hamcrest-more-matchers&lt;\/artifactId&gt;     &lt;version&gt;0.1&lt;\/version&gt;     &lt;scope&gt;test&lt;\/scope&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">import static com.github.seregamorph.hamcrest.TestLambdaUtils.unreferenceLambdaMethod; ... ThrowingFunction&lt;String, String&gt; fun = String::toLowerCase; Method method = unreferenceLambdaMethod(fun); assertEquals(&quot;toLowerCase&quot;, method.getName());<\/code><\/pre>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/522774\/\"> https:\/\/habr.com\/ru\/post\/522774\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/522774\/\">\n<p>\u042f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u2014 \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 method reference \u0432\u0438\u0434\u0430<\/p>\n<p>  <\/p>\n<pre><code class=\"java\">Function&lt;String, Integer&gt; fun = String::length;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 (\u0438\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u0435\u0433\u043e \u0438\u043c\u044f), \u0442.\u0435. \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e <code>java.lang.String.length()<\/code>. \u041a\u0430\u043a \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u043e\u0441\u044c, \u043d\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044f \u0432\u043e\u043b\u043d\u043e\u0432\u0430\u043b \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u043d\u0430\u0448\u043b\u0438\u0441\u044c \u0442\u0430\u043a\u0438\u0435 \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u043d\u0430 stackoverflow <a href=\"https:\/\/stackoverflow.com\/questions\/19845213\" rel=\"nofollow\">[1]<\/a>, <a href=\"https:\/\/stackoverflow.com\/questions\/21860875\" rel=\"nofollow\">[2]<\/a>, \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 GitHub, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u043a\u0430\u0441\u0430\u044e\u0442\u0441\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b <a href=\"https:\/\/github.com\/cronn-de\/reflection-util\" rel=\"nofollow\">[1]<\/a>, <a href=\"https:\/\/github.com\/jhalterman\/typetools\" rel=\"nofollow\">[2]<\/a>, <a href=\"https:\/\/github.com\/Hervian\/safety-mirror\" rel=\"nofollow\">[3]<\/a>, \u043d\u043e \u043d\u0435 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043d\u0435 \u0434\u0430\u0435\u0442 \u0440\u043e\u0432\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e. \u041d\u0430 \u0425\u0430\u0431\u0440\u0435 <a href=\"https:\/\/habr.com\/ru\/users\/ibessonov\/\" class=\"user_link\">ibessonov<\/a> \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0438\u043b <a href=\"https:\/\/habr.com\/ru\/post\/311788\/\">\u0441\u0432\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/a>, \u0430 <a href=\"https:\/\/habr.com\/ru\/users\/apangin\/\" class=\"user_link\">apangin<\/a> \u2014 \u0441\u0432\u043e\u0435 <a href=\"https:\/\/habr.com\/ru\/post\/311788\/#comment_9843134\">\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438<\/a>. \u0412\u0430\u0440\u0438\u0430\u043d\u0442 \u0410\u043d\u0434\u0440\u0435\u044f \u043c\u043d\u0435 \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u0441\u044f, \u043d\u043e \u0432\u0441\u043a\u043e\u0440\u0435 \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0438\u0441\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0438\u043c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u044d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 JDK, \u0432\u0441\u0435 \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 Java 8, \u043d\u043e \u043d\u0435 \u0432 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0437\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445. \u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0438\u043c\u0435\u0435\u0442 \u0440\u044f\u0434 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f <code>BiFunction<\/code> \u0438\u043b\u0438 <code>BiConsumer<\/code> \u043e\u043d \u0432\u044b\u0434\u0430\u0435\u0442 \u043d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u044d\u0442\u043e \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445).<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u043f\u0435\u0440\u0435\u0431\u0440\u0430\u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u044d\u0442\u0438\u0445 \u0438\u0437\u044c\u044f\u043d\u043e\u0432 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043f\u043e\u0437\u0434\u043d\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 JDK \u2014 SerializedLambda. \u0417\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0435\u0434 \u0441\u0440\u0430\u0437\u0443 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c\u0438, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0430\u043a <code>java.io.Serializable<\/code> (\u0442.\u0435. \u0441 <code>java.util.function.Function<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442), \u043d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-311302","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/311302","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=311302"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/311302\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=311302"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=311302"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=311302"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}