繁体   English   中英

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

[英]Why this java recursive method not creating infinite loop?

我是Android开发的新手,在尝试阅读代码示例时,我遇到了一个从内部调用的方法,所以逻辑上它应该创建一个调用自身的无限循环。 但事实并非如此。 为什么?

在我的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?
            }
        });
    }

并称之为:

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);
    }

编辑

这是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());
        }
    }

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 不会调用自身,因此这里没有无限递归。

它调用launchUserSpecificFragment ,它接收一个实现LoginDialogInterface作为参数的匿名类的实例。

匿名类包含一个调用onWishlistSelectedsuccessfulLoginOrRegistration方法,但调用onWishlistSelected并不一定执行该successfulLoginOrRegistration方法。 successfulLoginOrRegistration将被执行取决于逻辑launchUserSpecificFragment

请注意,调用onWishlistSelected位置在匿名类中,而不是直接在onWishlistSelected方法本身中。

如果仔细观察,您对onWishlistSelected的调用将放在名为successfulLoginOrRegistration的方法中。 这意味着,只有当successfulLoginOrRegistration被调用时, onWishlistSelected被调用。

那么什么时候会调用successfulLoginOrRegistration登录或注册? 我从你给出的代码量中无法知道这一点。

现在让我们假设successfulLoginOrRegistration被调用。 其结果是, onWishlistSelected被调用,但随后onWishlistSelected只会在下一次叫successfulLoginOrRegistration被调用。

现在您可能会问,“这两个方法调用不会填充堆栈跟踪吗?” 答案可能不是。 onWishlistSelected可能会先返回,以便代码的其他部分能够调用successfulLoginOrRegistration 因此堆栈跟踪不会溢出。

我将使用一个更容易理解的例子来说明这一点:

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();
        }
    });
}

这不会产生无限循环。 someMethod仅在用户按下按钮时执行。 当用户按下按钮时,将调用actionPerformedsomeMethod也是如此。 但是在用户再次点击按钮之前没有任何反应。

这个方法永远不会无限successfulLoginOrRegistration调用是因为有执行onWishlistSelected方法的successfulLoginOrRegistration接口。 总之你onWishlistSelected方法将只执行当你的interface将得到回调successfulLoginOrRegistration

onWishListSelected方法不会调用自身。 它定义了一个SuccessfulLoginOrRegistration方法,但从不调用它。 我相信这就是你想要的。

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