[英]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 都存储在一个名为listenerList
的javax.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.