[英]Why this java recursive method not creating infinite loop?
I am new to android development, while trying to read a code example, I encountered a method which is being called from within itself, so logically it should create an infinite loop of calling itself. 我是Android开发的新手,在尝试阅读代码示例时,我遇到了一个从内部调用的方法,所以逻辑上它应该创建一个调用自身的无限循环。 But it does not. 但事实并非如此。 why? 为什么?
In my MainActivity.java
在我的MainActivity.java
public void onWishlistSelected() {
launchUserSpecificFragment(new WishlistFragment(), WishlistFragment.class.getSimpleName(), new LoginDialogInterface() {
@Override
public void successfulLoginOrRegistration(User user) {
// If login was successful launch WishlistFragment.
onWishlistSelected(); // Why doesn't this create infine loop?
}
});
}
and calling it: 并称之为:
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_wish_list) {
onWishlistSelected();
return true;
} else if (id == R.id.action_cart) {
onCartSelected();
return true;
}
return super.onOptionsItemSelected(item);
}
EDIT 编辑
Here is the code inside launchUserSpecificFragment
这是launchUserSpecificFragment
的代码
private void launchUserSpecificFragment(Fragment fragment, String transactionTag, LoginDialogInterface loginListener) {
if (SettingsMy.getActiveUser() != null) {
replaceFragment(fragment, transactionTag);
} else {
DialogFragment loginDialogFragment = LoginDialogFragment.newInstance(loginListener);
loginDialogFragment.show(getSupportFragmentManager(), LoginDialogFragment.class.getSimpleName());
}
}
and replaceFragment
和replaceFragment
private void replaceFragment(Fragment newFragment, String transactionTag) {
if (newFragment != null) {
FragmentManager frgManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = frgManager.beginTransaction();
fragmentTransaction.setAllowOptimization(false);
fragmentTransaction.addToBackStack(transactionTag);
fragmentTransaction.replace(R.id.main_content_frame, newFragment).commit();
frgManager.executePendingTransactions();
} else {
Timber.e(new RuntimeException(), "Replace fragments with null newFragment parameter.");
}
}
onWishlistSelected
is not calling itself, so there is not infinite recursion here. onWishlistSelected
不会调用自身,因此这里没有无限递归。
It is calling launchUserSpecificFragment
, which receives an instance of an anonymous class implementing LoginDialogInterface
as an argument. 它调用launchUserSpecificFragment
,它接收一个实现LoginDialogInterface
作为参数的匿名类的实例。
The anonymous class contains a successfulLoginOrRegistration
method that calls onWishlistSelected
, but calling onWishlistSelected
doesn't necessarily execute that successfulLoginOrRegistration
method. 匿名类包含一个调用onWishlistSelected
的successfulLoginOrRegistration
方法,但调用onWishlistSelected
并不一定执行该successfulLoginOrRegistration
方法。 When successfulLoginOrRegistration
will be executed depends on the logic of launchUserSpecificFragment
. 当successfulLoginOrRegistration
将被执行取决于逻辑launchUserSpecificFragment
。
Note that the place where you call onWishlistSelected
is inside an anonymous class and not directly in the onWishlistSelected
method itself. 请注意,调用onWishlistSelected
位置在匿名类中,而不是直接在onWishlistSelected
方法本身中。
If you look closely that your call to onWishlistSelected
is put inside a method called successfulLoginOrRegistration
. 如果仔细观察,您对onWishlistSelected
的调用将放在名为successfulLoginOrRegistration
的方法中。 This means that only when successfulLoginOrRegistration
is called, onWishlistSelected
is called. 这意味着,只有当successfulLoginOrRegistration
被调用时, onWishlistSelected
被调用。
So when will successfulLoginOrRegistration
be called? 那么什么时候会调用successfulLoginOrRegistration
登录或注册? I cannot know this from the amount of code you have given. 我从你给出的代码量中无法知道这一点。
Now let's suppose that successfulLoginOrRegistration
is called. 现在让我们假设successfulLoginOrRegistration
被调用。 As a result, onWishlistSelected
is called, but then onWishlistSelected
will only be called the next time successfulLoginOrRegistration
is called. 其结果是, onWishlistSelected
被调用,但随后onWishlistSelected
只会在下一次叫successfulLoginOrRegistration
被调用。
Now you might ask, "Wouldn't the stack trace be filled with these two method calls?" 现在您可能会问,“这两个方法调用不会填充堆栈跟踪吗?” The answer is probably not. 答案可能不是。 onWishlistSelected
will probably return first, so that other parts of the code is able to call successfulLoginOrRegistration
. onWishlistSelected
可能会先返回,以便代码的其他部分能够调用successfulLoginOrRegistration
。 So the stack trace won't overflow. 因此堆栈跟踪不会溢出。
I will use an easier-to-understand example to illustrate this: 我将使用一个更容易理解的例子来说明这一点:
private static JButton btn = new JButton("press me");
public static void main(String[]args) throws Exception {
JFrame frame = new JFrame();
frame.add(btn);
someMethod();
frame.setVisible(true);
}
public static void someMethod() {
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("button pressed");
someMethod();
}
});
}
This will not create an infinite loop. 这不会产生无限循环。 someMethod
only executes when the user presses the button. someMethod
仅在用户按下按钮时执行。 When the user presses the button, actionPerformed
is called and so is someMethod
. 当用户按下按钮时,将调用actionPerformed
, someMethod
也是如此。 But then nothing happens, until the user clicks the button again. 但是在用户再次点击按钮之前没有任何反应。
This method will never call infinitely reason is there is successfulLoginOrRegistration
interface which is executing your onWishlistSelected
method. 这个方法永远不会无限successfulLoginOrRegistration
调用是因为有执行onWishlistSelected
方法的successfulLoginOrRegistration
接口。 In short your onWishlistSelected
method will execute only when your interface
will get callback in successfulLoginOrRegistration
. 总之你onWishlistSelected
方法将只执行当你的interface
将得到回调successfulLoginOrRegistration
。
onWishListSelected method is not calling itself. onWishListSelected方法不会调用自身。 It defines a successfulLoginOrRegistration method but never calls it. 它定义了一个SuccessfulLoginOrRegistration方法,但从不调用它。 This is what you want, I believe. 我相信这就是你想要的。
public void onWishlistSelected() {
boolean loginSuccess = false;
launchUserSpecificFragment(new WishlistFragment(), WishlistFragment.class.getSimpleName(), new LoginDialogInterface() {
@Override
public void successfulLoginOrRegistration(User user) {
// If login was successful launch WishlistFragment.
}
// set true when login successfully .
// loginSuccess = true;
});
// call untill successfully logged in.
if(loginSuccess == false){
onWishlistSelected();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.