为什么必须为方法引用显式指定类/对象名? [英] Why class/object name must be explicitly specified for method references?

查看:193
本文介绍了为什么必须为方法引用显式指定类/对象名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我想引用当前作用域中的方法时,我仍然需要
来指定类名(对于静态方法)或这个之前 ::
运算符。例如,我需要写:

When I want to refer to the method in the current scope I still need to specify class name (for static methods) or this before :: operator. For example, I need to write:

import java.util.stream.Stream;

public class StreamTest {
    public static int trimmedLength(String s) {
        return s.trim().length();
    }

    public static void main(String[] args) {
        System.out.println(Stream.of("  aaa  ", "  bb ", " c ")
                .mapToInt(StreamTest::trimmedLength).sum());
    }
}

对于这个,但有时候静态方法看起来过于拥挤,因为类名可能很长。如果编译器允许我简单地写 :: trimmedLength ,那将是很好的:

It's not so big problem for this, but sometimes look overcrowded for static methods as the class name can be quite long. It would be nice if compiler allowed me to write simply ::trimmedLength instead:

public static void main(String[] args) {
    System.out.println(Stream.of("  aaa  ", "  bb ", " c ")
            .mapToInt(::trimmedLength).sum());
}

但是Java-8编译器不允许这样做。对我来说,如果类/对象名称的解析方式与普通方法调用相同,那么它似乎会非常一致。这也支持方法引用的静态导入,这在某些情况下也很有用。

However Java-8 compiler doesn't allow this. For me it seems that it would be quite consistent if class/object name were resolved in the same manner as it's done for normal method call. This would also support static imports for method references which also can be useful in certain cases.

所以问题是为什么在Java 8中没有实现这样或类似的语法?这种语法会出现什么问题吗?或者根本不考虑它?

So the question is why such or similar syntax was not implemented in Java 8? Are there any problems which would arise with such syntax? Or it was not simply considered at all?

推荐答案

我不能代表Java开发人员,但有些事情需要考虑:

I can’t speak for the Java developers but there are some things to consider:

某些方法参考


  1. 对静态方法的引用,例如 ContainingClass :: staticMethodName

  2. 引用特定对象的实例方法,例如 containingObject :: instanceMethodName

  3. 对特定类型的任意对象的实例方法的引用,例如: ContainingType :: methodName

  4. 对构造函数的引用,例如: ClassName :: new

  1. Reference to a static method, e.g. ContainingClass::staticMethodName
  2. Reference to an instance method of a particular object, e.g. containingObject::instanceMethodName
  3. Reference to an instance method of an arbitrary object of a particular type, e.g. ContainingType::methodName
  4. Reference to a constructor, e.g. ClassName::new

编译器必须做一些工作才能消除歧义表格1和3以及有时会失败。如果允许使用表单 :: methodName ,则编译器必须消除三种不同形式之间的歧义,因为它可以是从1到3的三种形式中的任何一种。

The compiler already has to do some work to disambiguate the forms 1 and 3 and sometimes it fails. If the form ::methodName was allowed, the compiler had to disambiguate between three different forms as it could be any of the three forms from 1 to 3.

也就是说,允许表单 :: methodName 快捷地删除表单1到3中的任何一个仍然不会暗示它等同于 methodName(...)的形式,作为表达式 simpleName(arg opt 可以引用

That said, allowing the form ::methodName to short-cut any of the form 1 to 3 still wouldn’t imply that it is equivalent to the form methodName(…) as the expression simpleName ( argopt ) may refer to


  • 当前类或其超类和接口范围内的实例方法

  • 当前类或其超类范围内的 static 方法

  • 外部类或其范围内的实例方法超类和接口

  • 外部类或其超类范围内的 static 方法

  • 通过 import static

  • an instance method in the scope of the current class or its superclasses and interfaces
  • a static method in the scope of the current class or its superclasses
  • an instance method in the scope of an outer class or its superclasses and interfaces
  • a static method in the scope of an outer class or its superclasses
  • a static method declared via import static

所以说 :: name 应该被允许引用任何方法 name(...)可以引用暗示结合这两个列表的可能性,你应该三思而后行许愿。

So saying something like "::name should be allowed to refer to any method name(…) may refer to" implies to combine the possibilities of these two listings and you should think twice before making a wish.

作为最后一点,你仍然可以选择写一个像<$ c $这样的lambda表达式。 c> args - > name(args)这意味着解析 name 就像一个简单的方法调用 name(args)同时解决模糊问题,因为它消除了方法引用类型的选项3,除非你明确写出(arg1,otherargs) - > arg1.name(otherargs)

As a final note, you still have the option of writing a lambda expression like args -> name(args) which implies resolving name like a simple method invocation of the form name(args) while at the same time solving the ambiguity problem as it eliminates the option 3 of the method reference kinds, unless you write explicitly (arg1, otherargs) -> arg1.name(otherargs).

这篇关于为什么必须为方法引用显式指定类/对象名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆