标签: constructor-reference

Kotlin中有构造函数引用吗?

在Java中,我们有Class::new构造函数引用的语法.我知道,方法有可调用的引用,但构造函数如何?我的一个典型用例是工厂.

kotlin constructor-reference

82
推荐指数
1
解决办法
7611
查看次数

Runnable :: new vs new Runnable()

为什么以下第一个示例不起作用?

  • run(R::new);方法R.run未被调用.
  • run(new R());方法R.run 调用.

这两个例子都是可编译的.

public class ConstructorRefVsNew {

  public static void main(String[] args) {
      new ConstructorRefVsNew().run(R::new);
      System.out.println("-----------------------");
      new ConstructorRefVsNew().run(new R());
  }

  void run(Runnable r) {
      r.run();
  }

  static class R implements Runnable {

      R() {
          System.out.println("R constructor runs");
      }

      @Override
      public void run() {
          System.out.println("R.run runs");
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

  R constructor runs
  -----------------------
  R constructor runs
  R.run runs
Run Code Online (Sandbox Code Playgroud)

在第一个示例中,R调用构造函数,它返回lambda(不是对象):

但是,如何成功编译示例怎么可能呢?

java runnable java-8 constructor-reference

61
推荐指数
4
解决办法
4354
查看次数

使用本地类时构造函数引用无效?

给出以下代码:

package com.gmail.oksandum.test;

import java.util.ArrayList;
import java.util.List;

public class Test {

    public static void main(String[] args) {
    }

    public void foo() {
        class LocalFoo {

            LocalFoo(String in) {
                //Some logic
            }

        }

        List<String> ls = new ArrayList<>();
        ls.stream().map(LocalFoo::new); //Line 21
    }

}
Run Code Online (Sandbox Code Playgroud)

我的IDE没有给我任何错误.也就是说,直到我尝试构建项目并运行它.当我这样做它给我一个编译器错误,如下所示:

Error:(21, 24) java: incompatible types: cannot infer type-variable(s) R
    (argument mismatch; invalid constructor reference
      cannot access constructor LocalFoo(java.lang.String)
        an enclosing instance of type com.gmail.oksandum.test.Test is not in scope)
Run Code Online (Sandbox Code Playgroud)

现在,我想,给出错误消息,如果foo()是静态的,这不会发生.而且非常正确,只有当foo()是实例方法时才会发生这种情况.只有当LocalFoo是实例方法中的本地类时才会发生,并且只有在使用构造函数引用时才会发生(即从不是常规方法引用).

更重要的是,如果我将第21行改为

ls.stream().map(str -> new LocalFoo(str));
Run Code Online (Sandbox Code Playgroud)

编译器突然没有错误.

所以回顾一下.如果我尝试在实例方法中声明的本地类上使用构造函数引用,编译器会抱怨无法访问构造函数,我很困惑.

如果有人能够阐明为什么会发生这种情况,我们将不胜感激.谢谢.

java lambda java-8 method-reference constructor-reference

28
推荐指数
1
解决办法
1702
查看次数

Java 8可以动态实现接口以供方法参考吗?

我学习了Java 8的新功能.

我正在玩不同的例子,我发现了一个奇怪的行为:

public static void main(String[] args) {       
    method(Test::new);
}
static class Test{
}

private static void method(Supplier<Test> testSupplier){
    Test test = testSupplier.get();
}
Run Code Online (Sandbox Code Playgroud)

这段代码编译成功,但我不知道它是如何工作的.

为什么可以Test::new接受供应商?

供应商界面看起来很简单:

@FunctionalInterface
public interface Supplier<T> {    
    T get();
}
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference constructor-reference

19
推荐指数
2
解决办法
2774
查看次数

内部类的构造函数引用在运行时因VerifyError而失败

我正在使用lambda为内部类构造函数创建供应商ctx -> new SpectatorSwitcher(ctx).IntelliJ建议我将其SpectatorSwitcher::new改为.SpectatorSwitcher是我正在使用的类的非静态内部类.建议的代码编译得很好(使用maven)但我在执行时得到以下VerifyError:

Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    Test.lambda$runTest$8(LTest$Worker;)V @2: invokedynamic
  Reason:
    Type 'Test$Worker' (current frame, stack[1]) is not assignable to 'Test'
  Current Frame:
    bci: @2
    flags: { }
    locals: { 'Test$Worker' }
    stack: { 'Test$Worker', 'Test$Worker' }
  Bytecode:
    0000000: 2a2a ba00 0b00 00b6 000c b1            

    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2688)
    at java.lang.Class.getMethod0(Class.java:2937)
    at java.lang.Class.getMethod(Class.java:1771)
    at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
    at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Run Code Online (Sandbox Code Playgroud)

为什么javac/maven在编译时没有失败但仍然产生无效的字节代码?

编辑:问题似乎比简单调用复杂得多,这是重现它所需的代码:

import java.util.function.Function;

/**
 * @author …
Run Code Online (Sandbox Code Playgroud)

java lambda inner-classes java-8 constructor-reference

16
推荐指数
1
解决办法
689
查看次数

Java 8构造函数方法引用

我正在阅读perform message它附带的样本我重现..

@FunctionalInterface
public interface Action {
    public void perform();
}
Run Code Online (Sandbox Code Playgroud)

实施者

public final class ActionImpl implements Action {
    public ActionImpl() {
        System.out.println("constructor[ActionIMPL]");
    }

    @Override
    public void perform() {
        System.out.println("perform method is called..");
    }    
}
Run Code Online (Sandbox Code Playgroud)

来电者.

public final class MethodReferences {

    private final Action action;

    public MethodReferences(Action action) {
        this.action = action;
    }

    public void execute() {
        System.out.println("execute->called");
        action.perform();
        System.out.println("execute->exist");
    }

    public static void main(String[] args) {
        MethodReferences clazz = new MethodReferences(new ActionImpl());
        clazz.execute();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果调用此方法则将以下内容打印到输出中

constructor[ActionIMPL] …
Run Code Online (Sandbox Code Playgroud)

java java-8 method-reference constructor-reference

7
推荐指数
1
解决办法
5372
查看次数

默认方法中的自动构造函数匹配

我有一个PersonFactory如下界面:

@FunctionalInterface
public interface PersonFactory<P extends Person> {
    P create(String firstname, String lastname);

    // Return a person with no args
    default P create() {
        // Is there a way I could make this work?
    }
}
Run Code Online (Sandbox Code Playgroud)

Person类:

public class Person {
    public String firstname;
    public String lastname;

    public Person() {}

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望能够Person像这样实例化我的:

PersonFactory<Person> personFactory = Person::new;

Person p = personFactory.create(); // …
Run Code Online (Sandbox Code Playgroud)

java java-8 functional-interface method-reference constructor-reference

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

如何将类型参数传递给泛型类构造函数引用?

假设以下代码:

class ConstructMe<T> {}
data class Test<T> constructor(var supplier: () -> ConstructMe<T>) {}

fun main(args: Array<String>) {
    works<Int>()
    breaks<Int>()
}

fun <T> works() {
    Test<T>({ ConstructMe<T>() }) // (1) any one class type parameter can be removed like:
    Test({ ConstructMe<T>() })  // (2) still works (class type inferred by argument type)
    Test<T>({ ConstructMe() })  // (3) still works (argument type inferred by class type)
}

fun <T> breaks() {
    Test<T>(::ConstructMe) // type interference failed (should probably work like (3); compiler …
Run Code Online (Sandbox Code Playgroud)

generics reflection type-parameter kotlin constructor-reference

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

为什么它不输出“狗吃”

像这样的代码

public class LambdaTest {
    public static void main(String[] args) {
        final Animal animal = Dog::new;
        animal.eat();
    }
}

@FunctionalInterface
interface Animal {
    void eat();
}

class Dog implements Animal {

    public Dog() {
        System.out.println("dog init.");
    }

    @Override
    public void eat() {
        System.out.println("dog eat");
    }
Run Code Online (Sandbox Code Playgroud)

当我运行这段代码时,“dog init”。被打印到控制台,但“dog eat”却没有。这是为什么?有人能告诉我原因吗?

我预计会打印“dog init”和“dog eat”,但只打印了“dog init”。另外,我很困惑为什么在Animal animal = Dog::new;.

java constructor-reference

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

如何在Java 8中将[TypeArguments]与构造函数引用一起使用?

Java语言规范Java 8的第15.13节描述了这种形式的方法参考语法,用于创建构造函数引用:

    ClassType :: [TypeArguments] new
Run Code Online (Sandbox Code Playgroud)

例如:

    String s = "abc";
    UnaryOperator<String> test0 = String::new; // String(String) constructor.
    String s0 = test0.apply(s);
    System.out.println("s0 = " + s0); // Prints "abc".

    char[] chars = {'x','y','z'};
    Function<char[], String> test1 = String::new; // String(char[]) constructor.
    String s1 = test1.apply(chars);
    System.out.println("s1 = " + s1); // Prints "xyz"
Run Code Online (Sandbox Code Playgroud)

一切正常,但似乎绝对任何东西(不包括原语)也可以为[TypeArguments]提供,一切仍然有效:

这是一个愚蠢的例子来证明这一点:

    Function<String, String> test2 = String::<LocalDateTime, Thread[]>new; // Compiles !!!???
    String s2 = test2.apply("123");
    System.out.println("s2 = " + s2); // Prints "123"
Run Code Online (Sandbox Code Playgroud)

提出几个问题: …

java-8 method-reference constructor-reference

2
推荐指数
1
解决办法
145
查看次数