静态方法和实例方法的方法参考

2024-04-26

对于 Java 中的实例方法,我无法理解方法引用的概念

例如,在下面的示例中,编译器在列表行中给出错误。

我看过 String::toUpperCase 的例子。

我对这一点感到困惑 (1) String是类,toUpperCase是实例方法。 Java 允许 String::toUpperCase (2) 为什么在我的情况下不允许:- AppTest::makeUppercase

package mja;

import java.util.function.Function;
public class AppTest {

    public String makeUppercase(String source){
        return source.toUpperCase();
    }
    
    public void printFormattedString(String string, Function<String, String> formatter){
        System.out.println(formatter.apply(string));
    }
    
    public static void main(String[] args) {
        AppTest appTest = new AppTest();
        String source = "Hello World!";
        
        // Below statement compiled successfully
        appTest.printFormattedString(source, appTest::makeUppercase);

        // Getting error that non-static method can't be referenced from static context
        appTest.printFormattedString(source, AppTest::makeUppercase);
    }
}

为什么不允许AppTest::makeUppercase?

简短的回答是AppTest::makeUppercase无效“对特定类型的任意对象的实例方法的引用”. AppTest::makeUppercase必须实现接口Function<AppTest, String>为有效参考。

Details:

4 https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html#staticJava中方法引用的种类:

  1. ContainingClass::staticMethodName- 静态方法的引用
  2. containingObject::instanceMethodName- 对特定对象的实例方法的引用
  3. ContainingType::methodName- 对特定类型的任意对象的实例方法的引用
  4. ClassName::new- 对构造函数的引用

每一种方法引用都需要对应的Function接口实现。 您可以使用对特定类型的任意对象的实例方法的引用作为参数。 这种方法引用在方法引用中没有显式的参数变量,需要实现接口Function<ContainingType, String>。换句话说,左操作数的类型必须是AppTest使AppTest::makeUppercase可编译。String::toUpperCase工作正常,因为参数类型和实例类型相同 -String.

import static java.lang.System.out;

import java.util.Arrays;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;

class ReferenceSource {

    private String value;

    public ReferenceSource() {
    }

    public ReferenceSource(String value) {
        this.value = value;
    }

    public String doInstanceMethodOfParticularObject(final String value) {
        return ReferenceSource.toUpperCase(value);
    }

    public static String doStaticMethod(final String value) {
        return ReferenceSource.toUpperCase(value);
    }

    public String doInstanceMethodOfArbitraryObjectOfParticularType() {
        return ReferenceSource.toUpperCase(this.value);
    }

    private static String toUpperCase(final String value) {
        return Optional.ofNullable(value).map(String::toUpperCase).orElse("");
    }
}

public class Main {
    public static void main(String... args) {
        // #1 Ref. to a constructor
        final Supplier<ReferenceSource> refConstructor = ReferenceSource::new;
        final Function<String, ReferenceSource> refParameterizedConstructor = value -> new ReferenceSource(value);

        final ReferenceSource methodReferenceInstance = refConstructor.get();

        // #2 Ref. to an instance method of a particular object
        final UnaryOperator<String> refInstanceMethodOfParticularObject = methodReferenceInstance::doInstanceMethodOfParticularObject;

        // #3 Ref. to a static method
        final UnaryOperator<String> refStaticMethod = ReferenceSource::doStaticMethod;

        // #4 Ref. to an instance method of an arbitrary object of a particular type
        final Function<ReferenceSource, String> refInstanceMethodOfArbitraryObjectOfParticularType = ReferenceSource::doInstanceMethodOfArbitraryObjectOfParticularType;

        Arrays.stream(new String[] { "a", "b", "c" }).map(refInstanceMethodOfParticularObject).forEach(out::print);
        Arrays.stream(new String[] { "d", "e", "f" }).map(refStaticMethod).forEach(out::print);
        Arrays.stream(new String[] { "g", "h", "i" }).map(refParameterizedConstructor).map(refInstanceMethodOfArbitraryObjectOfParticularType)
                .forEach(out::print);
    }
}

此外,您可以看看this https://stackoverflow.com/questions/49349261/method-reference-difference-to-lambda and that https://stackoverflow.com/questions/23533345/what-does-an-arbitrary-object-of-a-particular-type-mean-in-java-8 thread.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态方法和实例方法的方法参考 的相关文章

随机推荐

  • 可以在子例程中使用模块吗?

    最近 我开始使用 OO Perl 并且为我正在开发的新项目创建了很多新对象 因为我不熟悉有关 OO Perl 的任何最佳实践 所以我们很急于完成它 P 我将大量此类代码放入每个函数中 sub funcx use ObjectX i don
  • “在捆绑 NSBundle 中找不到名为“MainStoryboard”的故事板”

    我已经在一个应用程序上工作了很长时间 突然我得到了这个 在捆绑包中找不到名为 MainStoryboard 的故事板 NS捆绑 我已经在 StackOverflow 上红色了类似的问题 并且我尝试了所有方法 包括 重命名故事板文件 重新添加
  • 类型错误:无法读取 null 的属性“名称”

    我有一个用户对象 他们可以在其中编辑他们的信息 电话号码 电子邮件等 我无法访问输入name在 的里面setState回调并继续获取TypeError Cannot read property name of null 但是当我登录时eve
  • Mozilla Firefox 不再支持dialog.showModal

    我有一个巨大的 asp 网站项目及其弹出窗口 使用自showModalDialog 几个月前mozilla更新了 这个功能出现了一些问题 所以我用了ModalDialog 填充 https github com niutech showMo
  • Tastypie 访问继承模型中的字段

    是否可以使用 tastypie 在相关模型上包含字段 根据我的下面的模型 如果我将一个 VideoContent 和一个 TextContent 实例保存到数据库 我就可以从我的内容资源中获取 2 个对象 但是没有任何其他字段可用 是否可以
  • 打开包含透视图等的 MTrimmedWindow 的多个实例

    我已经为我的 RCP 应用程序定义了一个 主窗口 作为 MTrimmedWindow 其中包含透视图 部件等 像往常一样 在 Application e4xmi 中 是否可以开通额外的以编程方式获取此主窗口的实例 类似于从 MPartDes
  • 布隆过滤器的实现

    使用布隆过滤器 我们将获得空间优化 cassandra 框架也有 Bloom Filter 的实现 但具体来说 这种空间优化是如何实现的呢 您可以使用以下示例了解它如何节省空间 假设我在 Google Chrome 团队工作 我想向浏览器添
  • Vba访问错误91

    我尝试运行这段代码 Public Sub Production UpdateStatus ByVal lngProductionId As Long ByVal NewProductionStatus As eProductionStatu
  • Heroku 中没有运行 Django 的 Web 进程

    我试图在heroku中部署我的应用程序 但是当我最终尝试在heroku中运行我的应用程序时 我在浏览器中看到了这样的内容 Application Error An error occurred in the application and
  • RSelenium:抓取加载缓慢的动态加载页面

    我不确定是否是因为我的网速很慢 但我正在尝试抓取一个在您向下滚动页面时加载信息的网站 我正在执行一个转到页面末尾的脚本 并等待 Selenium Chrome 服务器加载附加内容 服务器确实更新并加载新内容 因为我能够抓取最初不在页面上的信
  • 如何在python中获得逻辑正确的二进制移位

    正如标题所示 JavaScript 中有一个特定的运算符 gt gt gt 例如 在 JavaScript 中我们将得到以下结果 1000 gt gt gt 3 536870787 1000 gt gt 3 125 1000 gt gt g
  • Glass 的 SpeechRecognizer 权限不足错误

    我正在使用 GDK 先睹为快构建一个应用程序 但在沉浸式应用程序中无法进行语音识别 这是我的第一个安卓项目 我试着遵循这个 如何在 Android 手机中使用语音识别而不出现烦人的对话框 https stackoverflow com qu
  • SQL-计算数字列值的增加百分比

    我想根据 SQL 数据库中获得的值计算一些趋势 我特别感兴趣的是获取一列中值的增加百分比 如果值减少 则该值应该为负数 有人可以建议我该怎么做吗 我无法使用存储过程 Thanks 我的表有以下列 日期 数字 月份 数字 订单 数字 价格 实
  • 如何静态断言可变参数模板的参数包中的值?

    我正在创建一个可变参数模板 假设我有这样的东西 template
  • Android 媒体播放器使用服务

    我创建了一个MediaPlayer播放 mp3 文件的类 一切都很好 然后我的播放器在后台停止播放 我发现我的问题是我没有在服务中创建它 所以我开始阅读有关服务的信息 以了解如何创建一个服务并将其用于我的播放器 我的问题是 在服务和应用程序
  • Susy:根据屏幕尺寸改变列数

    在 Compass Sass 插件中 Susy http susy oddbird net 您可以在 base scss 文件中设置列数 对于桌面视图 我喜欢有 12 列 然而 对于移动视图来说 这列太多了 有没有办法更改移动显示的列数 我
  • 奇怪的 if 语句

    我发现这很奇怪if 别人代码中的语句 if variable 1 0 我不明白 它应该有两个 right 有人可以解释一下吗 条件式是一个按位运算符 https wiki python org moin BitwiseOperators比较
  • Rails 管理自定义:将 html 视图嵌入到仪表板中

    我们已从 Rails 管理起始页面删除了仪表板和历史记录 现在我们想嵌入一个谷歌分析页面 供用户查看 GA 的仪表板 该页面由一些简单的 HTML 组成 问题 如何在 Rails 管理仪表板中嵌入 html 页面 答案很简单 我需要创建以下
  • Windows 上 python 的长路径 - os.stat() 对于相对路径失败?

    我想访问 Windows 上的一些长 UNC 路径 我知道我需要使用 UNC 前缀 即 UNC 如果你逃脱了斜线 效果很好 os stat UNC server example com that has long path aaaaaaaa
  • 静态方法和实例方法的方法参考

    对于 Java 中的实例方法 我无法理解方法引用的概念 例如 在下面的示例中 编译器在列表行中给出错误 我看过 String toUpperCase 的例子 我对这一点感到困惑 1 String是类 toUpperCase是实例方法 Jav