标签: functional-interface

使用 MethodHandleProxies 的正确方法

在我当前正在处理的一个 Java 项目中,我动态加载类,然后使用反射 API 来查找并执行那些具有某些注释的类的方法。

执行实际执行的代码专门根据 Java-8 功能接口工作(出于兼容性原因),因此我需要一个中间阶段,将Method使用反射发现的实例转换为适当的功能接口。我使用MethodHandleProxies类来实现这一点。

再次出于兼容性原因,所讨论的功能接口是通用接口。这会在使用该方法时导致“未经检查的转换”警告MethodHandleProxies.asInterfaceInstance,因为该方法返回“裸”接口。

以下是一个简短的示例,重现了所涉及的主要步骤:

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TestClass {
    private String prefix;

    public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, SecurityException {
        // Use reflection to find method.
        Method method = Arrays.stream(TestClass.class.getDeclaredMethods()) // Stream over methods of ConsumerClass
                .filter(m -> m.isAnnotationPresent(Marker.class)) // Retain only methods with @Marker annotation
                .findFirst().get(); // Get first such method …
Run Code Online (Sandbox Code Playgroud)

java reflection java-8 functional-interface

5
推荐指数
1
解决办法
457
查看次数

为什么两个方法引用被编译到两个不同的地址?

我两次引用相同的方法,但引用不同。看这个例子:

import java.util.function.Consumer;

public class MethodRefTest {
    public static void main(String[] args) {
        new MethodRefTest();
    }

    public MethodRefTest() {
        Consumer<Integer> a = this::method;
        System.out.println(a);
        Consumer<Integer> b = this::method;
        System.out.println(b);
    }

    public void method(Integer value) {

    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

MethodRefTest$$Lambda$1/250421012@4c873330
MethodRefTest$$Lambda$2/295530567@776ec8df
Run Code Online (Sandbox Code Playgroud)

方法引用只不过是匿名类的语法糖吗?如果不是,我该怎么做才能始终获得相同的方法引用?(除了在字段中存储一次参考以供使用之外。)

(应用:我认为方法引用是观察者实现的一种更漂亮的方式。但是每次使用不同的引用,一旦添加观察者就不可能从可观察者中删除观察者。)

java functional-interface method-reference

5
推荐指数
1
解决办法
386
查看次数

在 lambda 函数中获取接口引用

考虑以下代码:

val hwnd = Handler()
hwnd.postDelayed(object : Runnable {
        override fun run()
            hwnd.postDelayed(this, 5000)
        }
}, 5000)
Run Code Online (Sandbox Code Playgroud)

这样,我可以通过thisrun()方法中使用(指的是 Runnable)将相同的 Runnable 发布到 Handler 。但是我怎么能只使用一个 lambda 表达式来做同样的事情呢?

val hwnd = Handler()
hwnd.postDelayed({
    //How to get "this" here?
}, 5000)
Run Code Online (Sandbox Code Playgroud)

这甚至可能吗?

java lambda android kotlin functional-interface

5
推荐指数
1
解决办法
311
查看次数

在 Java 中使用函数式接口的真实世界示例

我知道函数式接口意味着您可以完全/只有 1 个抽象方法和 1 个以上的默认方法,但我想知道如何将它与在 Java 中使用函数式接口的实际示例/情况相关联。

你能给出一个有效的情况/例子吗?

提前致谢!

java java-8 functional-interface

5
推荐指数
3
解决办法
5592
查看次数

为什么this.getClass给出自己的类名而不是匿名类名?

我通过在公共static void main()方法内实现接口I创建了匿名类。因此,通过Java 8的抽象方法test(),实现是从类C的imple()方法提供的。

因此,在public static void main()方法内部,打印_interface.getClass(),我得到了

package_path.Main $ $ Lambda $ 1/310656974这是绝对好的。因为它打印的是匿名类名。

另外,_interface指向堆中的匿名对象,因此我正在做_interface.test();。

因此,test()方法现在具有的第一条语句是打印类名称,

但是最终它显示的是package_path.C(告诉我C是类名)。那怎么可能?不应再次打印package_path.Main $$ Lambda $ 1/310656974吗?因为“这”意味着在测试方法内部是匿名的,对吗?

@java.lang.FunctionalInterface
interface I {
    void test();
}

class C {
    void imple() {
        System.out.println(this.getClass());
        System.out.println("Inside Implementation");
    }
}

class Main {
    public static void main(String[] args) {
        I _interface = new C()::imple;
        System.out.println(_interface.getClass());
        _interface.test();
    }
}
Run Code Online (Sandbox Code Playgroud)

java anonymous-class java-8 functional-interface

5
推荐指数
1
解决办法
83
查看次数

为什么带有 void 返回类型方法的函数接口接受任何返回类型方法?

我们有这个代码:

public class Test {
    public static Object foo() {
        System.out.println("Foo");
        return new Object();
    }

    public static void main(String[] args) {
        J j = Test::foo;
        j.m();
    }

}
interface J {
    void m();
}
Run Code Online (Sandbox Code Playgroud)

这段代码会起作用。关键线是

J j = Test::foo;
Run Code Online (Sandbox Code Playgroud)

虽然interface J声明它有一个void函数,但Test::foo返回一个Object.

虽然我们不能在实现接口时覆盖方法(这是显而易见的)。这仅在接口的方法为 时有效void,否则不会编译代码。有人能说出为什么这会以这种方式工作吗?:D

java void functional-interface

5
推荐指数
1
解决办法
945
查看次数

是否可以在 Java 中使用通用 Consumer 作为函数参数?

代码:

public void ifChangedString(String key, Consumer<String> consumer) {
    ...
    consumer.accept(getString(key));
}

public void ifChangedBoolean(String key, Consumer<Boolean> consumer) {
    ...
    consumer.accept(getBoolean(key));
}
Run Code Online (Sandbox Code Playgroud)

是否可以制作单个方法public <T> void ifChanged(String key, Class<T> clazz, Consumer<T> consumer)

显而易见的解决方案是public void ifChanged(String key, Consumer<Object> consumer)但我不想Object用作参数类型,最好使用上述几种方法。

问题是对于accept我需要的方法? super XXX,只有 super 是 Object。那么有可能吗?

java java-8 functional-interface

5
推荐指数
1
解决办法
303
查看次数

多行 lambda

我有这个代码,它有效:

  new JdbcTemplate(new SingleConnectionDataSource(c, true))
        .query("select id, name from PLAYERS", (rs, rowNum) ->
            new Player(rs.getString("id"), rs.getString("name")) // oneline
        );
Run Code Online (Sandbox Code Playgroud)

但是我现在需要在新的 Player() 部分添加多个语句。我尝试将它们括在括号中,但似乎不起作用。什么是正确的语法?

java java-8 functional-interface

5
推荐指数
2
解决办法
2711
查看次数

Consumer&lt;?&gt; 和 Consumer&lt;T&gt; 似乎并不完全等效 - 与任何 Consuming 功能接口相同

我有一个我不明白的 java 编译器错误。似乎消费者< ? > 和 Consumer< T >(带有 T extends Object)在方法签名参数中是不等价的。请查看以下代码:

import java.util.function.Consumer;

public class MyClass {

    public void joker(Consumer<?> fct) {}
    public <T> void generic(Consumer<T> fct) {}
    public void myConsumer(String s) {}

    public void doesNotCompile()
    {
        joker(this::myConsumer); // COMPILE ERROR : (In Eclipse : ) The type MyClass does not define myConsumer(Object) that is applicable here
        generic(this::myConsumer); // Works fine : how come are "T" and "?" not equivalent here ?

        // The following also works fine as …
Run Code Online (Sandbox Code Playgroud)

java generics functional-interface method-reference

5
推荐指数
1
解决办法
71
查看次数

Java 函数式接口和 Lambda 表达式

鉴于以下代码,有人可以解释为什么断言返回 true 吗?尽管已经进行了无数次搜索,但我无法得到任何适当的答案,说明为什么会出现这种情况,Java 特性是什么导致了这种行为,以及我在类似地创建这样的接口时会遇到哪些限制/要求作为这个。

interface X {
  default int foo() {return 1;}
  String bar();
}

public class Exercise{
  public static void main(String[]arg){
    X foo1=()->"hello";
    assert (foo1.bar()).equals("hello");
  }
}
Run Code Online (Sandbox Code Playgroud)

java lambda functional-interface

5
推荐指数
1
解决办法
246
查看次数