简体   繁体   English

Java,编译器如何知道在这个 lambda 表达式中调用哪个构造函数

[英]Java, How does the compiler know which constructor to call in this lambda expression

I have a question, I'm learning java with a Book, and as I've copied some code in there (and made some changes) and made some investigations, I noticed something odd..., here is the code我有一个问题,我正在用一本书学习 Java,并且当我在其中复制了一些代码(并进行了一些更改)并进行了一些调查时,我发现了一些奇怪的东西......,这是代码

public static void main(String[] args)
{
    Timer timer = new Timer(1000, (event) ->
    {
        System.out.println("At the Tone, the time is" + Instant.ofEpochMilli(event.getWhen()));
        Toolkit.getDefaultToolkit().beep();
    });

    timer.start();
    JOptionPane.showMessageDialog(null, "Quit?");
    System.exit(0);

}

It's just a code that notifies you if a second passes.这只是一个代码,如果一秒钟过去了,它会通知您。 (this code compiles and runs smoothly) (此代码编译运行顺利)

as you can see Timer Constructor requires 2 pars (int, ActionListener)如您所见,计时器构造函数需要 2 个部分(int、ActionListener)

public Timer(int delay, ActionListener listener)

and the ActionListener Interface has one method that is actionPerformed and requires ActionEvent parameter并且 ActionListener 接口有一个方法是 actionPerformed 并且需要 ActionEvent 参数

public void actionPerformed(ActionEvent e);

Now here is my question, when calling this actionPerformed Method in that lambda expression above How does the compiler know which constructor to call to instantiate ActionEvent without feeding him any clues about the parameters, ActionEvent has no "No argument Constructor" and the method getWhen() is not static (obj must be instantiated)现在这是我的问题,当在上面的 lambda 表达式中调用这个 actionPerformed 方法时,编译器如何知道调用哪个构造函数来实例化 ActionEvent 而不向他提供有关参数的任何线索,ActionEvent 没有“无参数构造函数”和方法 getWhen( ) 不是静态的(必须实例化 obj)

Here are all the constructors of ActionEvent:以下是 ActionEvent 的所有构造函数:

public ActionEvent(Object source, int id, String command)

public ActionEvent(Object source, int id, String command, int modifiers)

public ActionEvent(Object source, int id, String command, long when,
                   int modifiers)

I really hope I made myself clear!, Thank you我真的希望我说清楚了!,谢谢

The compiler does not know!编译器不知道! ;-) ;-)
It is the Timer instance that will create the ActionEvent instance at runtime every delay and the Timer instance will call the ActionListener method actionPerformed with the ActionEvent it created. Timer实例将在每次delay运行时创建ActionEvent实例, Timer实例将使用它创建的ActionEvent调用ActionListener方法actionPerformed

You can have a look at one of the implementation here:您可以在此处查看其中一个实现:
http://developer.classpath.org/doc/javax/swing/Timer-source.html http://developer.classpath.org/doc/javax/swing/Timer-source.html

/**
 * Fire the action event, named "Timer" and having the numeric
 * identifier, equal to the numer of events that have been
 * already fired before.
 */
void fireActionPerformed()
{
  fireActionPerformed(new ActionEvent(this, ticks++, "Timer"));
}

If we look at the source code of javax.swing.Timer , we note that all the ActionListeners of the Timer are stored on a javax.swing.event.EventListenerList , called listenerList .如果我们查看javax.swing.Timer的源代码,我们会注意到Timer所有 ActionListener 都存储在一个名为listenerListjavax.swing.event.EventListenerList They are called in this line(s):它们在这一行中被调用:

fireActionPerformed(new ActionEvent(Timer.this, 0, getActionCommand(),
                                                    System.currentTimeMillis(),
                                                    0));

With fireActionPerformed:使用 fireActionPerformed:

protected void fireActionPerformed(ActionEvent e) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();

        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i=listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==ActionListener.class) {
                ((ActionListener)listeners[i+1]).actionPerformed(e);
            }
        }
    }

The regular constructor selection process applies.常规构造函数选择过程适用。

The Timer constructor just receives a listener and registers it in its listeners list. Timer构造函数仅接收一个侦听器并将其注册到其侦听器列表中。 When the timer ticks (where listener should be called), the Timer instance creates a new ActionEvent (See Timer.java:245 ) and passes it over to the registered listeners.当计时器滴答Timer.java:245 (应调用侦听器的位置), Timer实例创建一个新的 ActionEvent(参见Timer.java:245 )并将其传递给注册的侦听器。

So simply saying, the compiler doesn't create it for you.简单地说,编译器不会为您创建它。 Instead Timer class does.相反, Timer类可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java 如何知道在 class 中使用哪个构造函数? - How does Java know which constructor to use in a class? Java如何知道在使用lambda表达式时应该覆盖哪个方法 - How Java know which method should be override when use lambda expression 在Java中使用完整构造函数调用作为lambda表达式的方法引用 - Method reference with a full constructor call as a lambda expression in Java java 编译器是否知道如何优化此类代码? - Does the java compiler know how to optimize such code? java编译器如何知道继承的方法? - How does the java compiler know of inherited methods? java 如何知道 lambda 参数的类型? - How does java know the type of a lambda parameter? Java class inheritance 编译器怎么知道需要使用哪种方法 - Java class inheritance how does the compiler know which method needs to be used 如何判断在Java中使用了哪个构造函数,或者如何知道实例具有多少个参数? - How to judge which constructor is used in java, or how to know how many parameter does an instance have? 如何使用java lambda表达式将List传递给新对象的构造函数? - How to pass a List to a constructor of a new object using java lambda expression? 编译器如何知道 Lamba 正在实现哪个 class? - How does the compiler know which class the lamba is implementing?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM