当前位置: 首页 > 面试题库 >

方法引用如何与具有不同实现函数名称的功能接口兼容?

许曦
2023-03-14
问题内容

这里,对静态方法isPrime()的引用作为第一个参数传递给numTest()。这是有效的,因为isPrime与IntPredicate功能接口兼容。因此,表达式MyIntPredicates
:: isPrime评估为对对象的引用,其中 isPrime()提供IntPredicate中test()的实现。

isPrime()如何 使用 test()以外 的其他引用/名称提供test()的实现。 我想这就是在Java
8中提供更多灵活性和可能性的关键所在。有人可以解释这是否是新的吗?以及它是如何工作的?

谢谢 !

//Demonstrate a method reference for a static method.
//A functional interface for numeric predicates that operate
//on integer values.
interface IntPredicate {
    //the abstact to be implemented with something compatible
    boolean test(int n);
}

// This class defines three static methods that check an integer
// against some condition.
class MyIntPredicates {

    // A static method that returns true if a number is prime.
    static boolean isPrime(int n) {
        if (n < 2)
            return false;
        for (int i = 2; i <= n / i; i++) {
            if ((n % i) == 0)
                return false;
        }
        return true;
    }

    // A static method that returns true if a number is even.
    static boolean isEven(int n) {
        return (n % 2) == 0;
    }

    // A static method that returns true if a number is positive.
    static boolean isPositive(int n) {
        return n > 0;
    }
}

public class MethodRefDemo {
    // This method has a functional interface as the type of its
    // first parameter. Thus, it can be passed a reference to any
    // instance of that interface, including one created by a
    // method reference.
    static boolean numTest(IntPredicate p, int v) {
        return p.test(v);
    }


    public static void main(String args[]) {
        boolean result;
        // Here, a method reference to isPrime is passed to numTest().
        result = numTest(MyIntPredicates::isPrime, 17);
        if (result)
            System.out.println("17 is prime.");
        // Next, a method reference to isEven is used.
        result = numTest(MyIntPredicates::isEven, 12);
        if (result)
            System.out.println("12 is even.");
        // Now, a method reference to isPositive is passed.
        result = numTest(MyIntPredicates::isPositive, 11);
        if (result)
            System.out.println("11 is positive.");
    }
}

问题答案:

这是工作中的lambda的示例。它是Java 8中的新功能,它基本上允许运行时使用您定义的实现为您创建功能接口的实例。

Brian
Goetz写了一篇有关lambda(和方法引用)如何在编译和运行时工作的文档。



 类似资料:
  • 问题内容: 我是Swift的新手,我已经遍历了一些教程,其中许多教程使用同一个名称多次定义了一个函数。 我已经习惯了其他编程语言,否则将无法执行此操作。 因此,我检查了官方的Swift手册,还检查了override关键字,以了解可以得到的结果,但是仍然无法理解以下代码: 从我看到的函数tableView设置在第1行和第5行,我注意到的唯一区别是第一个tableView函数返回,而第二个函数返回(U

  • 问题内容: 假设我必须实现在两个不同的包中声明的两个不同的接口(在两个不同的独立项目中)。 我有包装 并包装 在我的包里 如何处理这种情况? 问题答案: 正如常见问题解答所提到的 其他语言的经验告诉我们,使用具有相同名称但签名不同的多种方法有时会很有用,但在实践中也可能会造成混淆和脆弱。 在Go的类型系统中,仅按名称进行匹配并要求类型一致是简化的主要决定 。 在您的情况下,您将满足两个接口。 您可

  • 我有一个采访问题-C#,是否可以在一个类中实现,从接口继承有两个具有相同名称和相同签名的方法?

  • 问题内容: 我正在尝试获得类似这样的功能的参考: 我有以下错误: 如何获得具有指定参数的功能? 问题答案: 由于有两个名称相同但签名不同的方法,因此您必须指定所需的方法: 或者(如@Antonio正确指出的): 如果您需要将类的实例作为第一个参数的咖喱函数,则可以以相同的方式进行,只有签名不同(将@Antonios注释与您的问题进行比较):

  • 问题内容: 我正在尝试建立一个实现和的类。这两个接口都定义了方法,但是返回类型不同: K的类型擦除导致这两个方法签名冲突。我不能拥有它们中的一个,因为它是一个无效的覆盖,并且我不能拥有两个,因为它们具有相同的签名。有什么方法可以使这两个接口共存? 问题答案: 我认为在这种特殊情况下是不可能的。如果两个类都返回了对象类型,那么您将有机会,但是由于您混合了基本类型和对象类型,因此没有兼容的类型同时支持

  • 问题内容: 我有两个Java接口和一个实现类。 (我已经使用Eclipse直接运行程序,并且我没有尝试通过从命令行进行显式编译来检查任何编译器警告等)。 为什么它们运行没有问题?为什么Java允许这样做,即使它满足两个接口的“合同”,却在实现类时造成歧义? 更新了示例。 问题答案: Java语言规范的第8.1.5节专门允许这种情况: 类中的单个方法声明可以实现多个超级接口的方法。例如,在代码中: