Search code examples
javaloopsmethods

Is there a disadvantage to make two methods call each other back and forth?


Making a school exercise, I found myself calling two methods back and forth until the user activates the stop flag. Checking the teacher's answer, they used a while-loop instead to loop these two methods.

I want to know if there is a disadvantage (maybe resource-wise?) to doing this my way.

Disclaimer: I have some bad practice in this code (mixed languages, calling two methods to just start the script), please don't call me on out on it since i am aware of these.

The code in question is: exe() -> switch case 1 or 2 <calls rectangleFunc or triangleFunc> -> exe() gets called again -> ...

package cui;

import java.util.Scanner;
import domein.*;

public class VormApplicatie
{
int iterations;
int legalRectangles;
int legalTriangles;

    public static void main(String[] args)
    {
         new VormApplicatie().beginProcess();
    }
    
    private void beginProcess()
    {
        iterations = 0;
        legalRectangles = 0;
        legalTriangles = 0;
        System.out.println("Rechthoeken en driehoeken\n-------------------------");
        exe();
    }
    
    private void exe()
    {
        Scanner input = new Scanner(System.in);
        
        int choice;
        
        do
        {
            System.out.printf("0: quit\n1: rectangle\n2: triangle\nPlease input choice:");
            choice = input.nextInt();
        
        }while(choice < 0 && choice > 2);
        
        switch(choice)
        {
        case 0 -> finishProcess();
        case 1 -> rectangleFunc(input);
        case 2 -> triangleFunc(input);
        default -> {System.out.println("Unexpected error occured."); finishProcess();}
        }
        input.close();
    }
    
    private void rectangleFunc(Scanner input)
    {
        int length, width;
        
        System.out.print("Please input length: ");
        length = input.nextInt();
        
        System.out.print("Please input width: ");
        width = input.nextInt();
        
        iterations++;
        Rechthoek localRect = new Rechthoek(length, width);
        legalRectangles += localRect.berekenOppervlakte() > 50 ? 1 : 0;
        
        exe();
        
        /*int choice = makeChoiceToContinue(input);
        
        switch(choice)
        {
        case 0 -> System.out.println("Process stopped.");
        case 1 -> finishProcess();
        case 2 -> exe();
        }*/
    }
    
    private void triangleFunc(Scanner input)
    {
        int first,second,third;
        
        System.out.print("Please input length of first side: ");
        first = input.nextInt();
        System.out.print("Please input length of second side: ");
        second = input.nextInt();
        System.out.print("Please input length of third side: ");
        third = input.nextInt();
        
        iterations++;
        Driehoek localTri = new Driehoek(first, third, second);
        legalTriangles += localTri.isRechthoekig() == true ? 1 : 0;
        
        exe();
        /*
        int choice = makeChoiceToContinue(input);
        
        switch(choice)
        {
        case 0 -> System.out.println("Process stopped.");
        case 1 -> finishProcess();
        case 2 -> exe();
        }*/
    }
    
    private void finishProcess()
    {
        System.out.printf(
                "Overzicht vormen:\n\n"
                + "Totaal aantal vormen: %d\n\n"
                + "Aantal rechthoeken met opp > 50: %d\n\n"
                + "Aantal rechthoekige driehoeken: %d",
                iterations, legalRectangles, legalTriangles);
    }
    
    /*private int makeChoiceToContinue(Scanner input)
    {
        int choice;
        do
        {
            System.out.print("Do you want to stop(0) or continue(1)?\nInput corresponding number: ");
            choice = input.nextInt();
        }while(choice != 0 && choice != 1 && choice != 2); 
        return choice;
    }*/

}

Solution

  • Yes. When a method returns it returns back to what called it. Therefore, the system needs to remember where return; should go to. In your code, you never actually return (exe() never returns; instead it calls e.g. triangleFunc. triangleFunc() never returns; instead it calls exe()) - but that doesn't matter, the system doesn't know that these never return. So, it has to remember. Every time you call a method, the location you called it from is written on a little note and that note is added to the stack, which is like one of those old timey big pins you stick orders onto. Anytime a method returns, the top note is fetched off of the pin to know where to return to.

    Your code never returns, so, that stack of notes on the pin grows evermore. Eventually, it grows so much the pin has no room. At that point, a StackOverflowError will occur and your application will crash.

    Is that likely to happen? Eh, you'd need to press 1/2 a few thousand times probably. But, the point is, this is 'bad code' because of this reason and nobody writes it this way for any project other than academic/just to learn. Using this style of calling back and forth wouldn't pass code review or would actually end up causing actual trouble in many situations. Hence, this is simply not how it is done. If I was your teacher, I'd give you quite a few minus points for this.