简体   繁体   English

为什么这个java递归方法没有创建无限循环?

[英]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. 匿名类包含一个调用onWishlistSelectedsuccessfulLoginOrRegistration方法,但调用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 . 当用户按下按钮时,将调用actionPerformedsomeMethod也是如此。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM