标签: method-reference

为什么'T.super.toString()'和'super :: toString'使用合成访问器方法?

考虑以下一组表达式:

class T {{
/*1*/   super.toString();      // direct
/*2*/   T.super.toString();    // synthetic
        Supplier<?> s;
/*3*/   s = super::toString;   // synthetic
/*4*/   s = T.super::toString; // synthetic
}}
Run Code Online (Sandbox Code Playgroud)

这给出了以下结果:

class T {
    T();
     0  aload_0 [this]
     1  invokespecial java.lang.Object() [8]
     4  aload_0 [this]
     5  invokespecial java.lang.Object.toString() : java.lang.String [10]
     8  pop           // ^-- direct
     9  aload_0 [this]
    10  invokestatic T.access$0(T) : java.lang.String [14]
    13  pop           // ^-- synthetic
    14  aload_0 [this]
    15  invokedynamic 0 get(T) : java.util.function.Supplier [21]
    20  astore_1 [s] …
Run Code Online (Sandbox Code Playgroud)

java super java-8 synthetic method-reference

13
推荐指数
1
解决办法
563
查看次数

Java 8中的方法参考

public class Car {

    private int maxSpeed;

    public Car(int maxSpeed) {
        this.maxSpeed = maxSpeed;
    }

    public int getMaxSpeed() {
        return maxSpeed;
    }
}
Run Code Online (Sandbox Code Playgroud)

我们可以按以下方式对汽车列表进行排序

    Car carX = new Car(155);
    Car carY = new Car(140);

    List<Car> cars = new ArrayList<>();
    cars.add(carX);
    cars.add(carY);

    cars.sort(Comparator.comparing(Car::getMaxSpeed));
Run Code Online (Sandbox Code Playgroud)

如果我们看到方法的签名Comparator.comparing,则输入参数类型为Function<? super T, ? extends U>

在上面的例子中,是如何Car::getMaxSpeed被转换为Function<? super T, ? extends U>而以下不编译?

  Function<Void, Integer> function = Car::getMaxSpeed;
Run Code Online (Sandbox Code Playgroud)

java lambda java-8 method-reference

13
推荐指数
2
解决办法
3186
查看次数

此表达式的目标类型必须是MethodReferences中的功能接口

为什么以下代码无法编译.

Consumer con = (s) -> System.out::println;

它说

此表达式的目标类型必须是功能接口

即使消费者是功能界面.以下工作正常.

Consumer con2 = (s) -> {System.out.println(s);};

java-8 method-reference

13
推荐指数
2
解决办法
3万
查看次数

静态引用(带有::)返回接口的方法

我有几个实现相同方法的预定义静态"处理器",例如:

default double process(double num){
Run Code Online (Sandbox Code Playgroud)

样品:

public class Test {
    public static void main(String[] args) {
        test(Test::processor1, 1d);
        test(Test::processor2, 1d);
    }

    static double processor1(double num){
        return num * 10;
    }

    static double processor2(double num){
        return num * 20;
    }
    //...

    static void test(Function<Double, Double> f, double d){
        // Do something util here
        System.out.println(f.apply(d));
    }   
    ...
Run Code Online (Sandbox Code Playgroud)

现在假设我有一些对象可以提供额外的"处理器"列表.

我正在尝试使用a interface来定义那些额外的"处理器".

    static interface IProcessor{
        double process(double num);
    }
Run Code Online (Sandbox Code Playgroud)

使用附加"处理器"实现对象:

    static class SomeObject{
        // Just return one but should be a list...
        static …
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface method-reference

12
推荐指数
1
解决办法
1102
查看次数

有没有办法在jshell中为顶级函数使用方法引用?

假设我在jshell中这样做:

jshell> void printIsEven(int i) {
   ...>     System.out.println(i % 2 == 0);
   ...> }
|  created method printIsEven(int)

jshell> List<Integer> l = Arrays.asList(7,5,4,8,5,9);
l ==> [7, 5, 4, 8, 5, 9]

jshell> l.forEach(/* ??? */); // is it possible to use a method reference here?
Run Code Online (Sandbox Code Playgroud)

在普通程序中,我可以l.forEach(this::printIsEven)在非静态上下文中或l.forEach(MyClass::printIsEven)在名为的类的静态上下文中编写MyClass.

this::printIsEven在jshell中使用不起作用,因为jshell在静态上下文中执行语句,但是你不能使用静态方法引用,因为没有类名称来加前缀::printIsEven,而尝试l.forEach(::printIsEven)只是一个语法错误.

java method-reference java-9 jshell

12
推荐指数
1
解决办法
468
查看次数

用于指定泛型方法的方法引用的语法

我在"Java - 初学者指南"中阅读了以下代码

interface SomeTest <T>
{
    boolean test(T n, T m);
}

class MyClass
{
    static <T> boolean myGenMeth(T x, T y)
    {
        boolean result = false;
        // ...
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

以下声明有效

SomeTest <Integer> mRef = MyClass :: <Integer> myGenMeth;
Run Code Online (Sandbox Code Playgroud)

关于上述代码的解释有两点

1 - 当泛型方法被指定为方法引用时,其类型参数::位于方法名称之前和之后.

2 - 如果指定了泛型类,则type参数在类名后面,并在其前面::.

我的查询: -

上面的代码是第一个引用点的示例

有人能为我提供一个实现第二个引用点的代码示例吗?

(基本上我不明白第二个引用点).

java generics method-reference

11
推荐指数
1
解决办法
4023
查看次数

使用::时Java 8缺少参数

Java 8只::通过方法名称启用方法引用.

protected Object loadBeanController(String url) throws IOException {
    loader = new FXMLLoader(getClass().getResource(url));
    ApplicationContext context = MyProjectClass.getApplicationContext();

    loader.setControllerFactory(context::getBean);

    return loader.getController();
}
Run Code Online (Sandbox Code Playgroud)

但是,根据BeanFactory接口(Spring)getBean() getBean不采用空参数 - 一些参数值是预期的:

getBean(String name)
getBean(String name,Class requiredType)
getBean(String name,Object [] args)

这是如何解决的?

java spring spring-mvc java-8 method-reference

11
推荐指数
1
解决办法
433
查看次数

将非最终对象传递给方法引用

什么是第二次s.get()返回"ONE"的解释?

String x = "one";
Supplier<String> s = x::toUpperCase;
System.out.println("s.get() = " + s.get());
x = "two";
System.out.println("s.get() = " + s.get());
Run Code Online (Sandbox Code Playgroud)

更新:

比较它:

String x = "one";
Supplier<String> s = () -> x.toUpperCase();
System.out.println("s.get() = " + s.get());
x = "two";
System.out.println("s.get() = " + s.get());
Run Code Online (Sandbox Code Playgroud)

它会抛出一个编译错误.

java lambda expression-evaluation java-8 method-reference

11
推荐指数
2
解决办法
258
查看次数

如何将Java Supplier绑定到对象的实例?

如何将Java绑定Supplier到Object的现有实例?例如,如果我想compareTo()用这个标题编写我自己的方法:

public static int myCompareTo(Object o1, Object o2, Supplier<Comparable> supplier) {...}
Run Code Online (Sandbox Code Playgroud)

我想能够称之为:

myCompareTo("Hello", "Hello2", String::length);
Run Code Online (Sandbox Code Playgroud)

where String(带大写字母)是一个类而没有对象.那么如何将实例绑定o1到供应商?

java method-reference

11
推荐指数
1
解决办法
900
查看次数

我们可以使用java.util.function获得方法名称吗?

我试着做:

public class HelloWorld {
     public static void main(String... args){
        final String string = "a";
        final Supplier<?> supplier = string::isEmpty;
        System.out.println(supplier);
     }
}
Run Code Online (Sandbox Code Playgroud)

我得到:

HelloWorld$$Lambda$1/471910020@548c4f57
Run Code Online (Sandbox Code Playgroud)

我想拿线isEmpty。我怎样才能做到这一点?

编辑:我创建的方法的代码是此之一:

public class EnumHelper {
    private final static String values = "values";
    private final static String errorTpl = "Can't find element with value `{0}` for enum {1} using getter {2}()";

    public static <T extends Enum<T>, U> T getFromValue(T enumT, U value, String getter) {
        @SuppressWarnings("unchecked")
        final T[] elements = (T[]) ReflectionHelper.callMethod(enumT, values); …
Run Code Online (Sandbox Code Playgroud)

java methods functional-programming java-8 method-reference

11
推荐指数
2
解决办法
404
查看次数