-1

Currently I am struggeling with an trivial problem I guess. When executing my main methode I get an stackoverflow error. It's because the Artist class creats an instance in the Language class to access some parameters comming from the Artist class (methode). Do you have any suggestions how I can set up the construct based on the current setup.

There are five classes interacting with each other:

First class is the Overview class with the main methode. She should create an instance of my control class and execute the methode control.displayArtist(salary, name):

public class Overview {
    private static Control control;
    private static String name;
    private static int salary;
    

public static void main (String[]args) {
        control = new Control();
        control.displayArtist(salary, name);
        
    }
}

The seccond class is the class Control. The class Control creates an instance of the class Language and consists of the methode displayArtist(int salary, String name). This method is callded directly in the main methode of the Overview Class:

public class Control {

    private Language language;


public Control() {
    language = new Language();
    
}

public void displayArtist(int salary, String name) {
    language.displayArtistAndSalary(name, salary);
}

}

The Language class has all the println statements and is creating an instance of the Artist, for the methode displayArtistAndSalary(String name, int salary) to handle the String name and the int salary coming from the Artist class:

public class Language {
    
    private Artist artist;
    
    public Language () {
    
    artist = new Artist();
        
    }
public void specifyArtist() {
    System.out.println("Who is the artist? ");
}

public void specifyArtistSalary() {
    System.out.println("How much does the artist earn? ");
}

    
public void displayArtistAndSalary(String name, int salary) {
    System.out.println("Artist: " + artist.getName(name));
    System.out.println("Salary: " + artist.getSalary(salary));

}

}

Based on the input from the InputReader class:

import java.util.Scanner;

public class InputReader {

    Scanner sc;
    private Language language;

    
public InputReader () {
    sc = new Scanner(System.in);
    language = new Language();
}

public void addArtist(String name) {
    language.specifyArtist();
    name = sc.nextLine();
    

}

public void addArtistSalary (int salary) {
    language.specifyArtistSalary();
     salary = sc.nextInt();
         
}

    
}

the artist class returns the name and the salary in the methodes getName (String name) and getSalary(int salary):

public class Artist {
    
    private InputReader inputReader;
        

public Artist() {
    inputReader = new InputReader();

    }
    
    public String getName (String name){
        inputReader.addArtist(name);
        return name;

    }
    public int getSalary(int salary){
        inputReader.addArtistSalary(salary);
        return salary;

    }

}
6
  • Can you show a minimal reproducible example? Commented Jan 14, 2021 at 13:55
  • Your main method is inside the constructor of Overview. This wouldn't even compile? Commented Jan 14, 2021 at 13:55
  • @maloomeister it compiles but i am getting this error when run the program: Exception in thread "main" java.lang.StackOverflowError Commented Jan 14, 2021 at 13:59
  • and why is the main method in the constructor of overview? @GidoLindenhorst Commented Jan 14, 2021 at 14:01
  • 2
    Does this answer your question? Circular dependency in java classes Commented Jan 14, 2021 at 14:09

2 Answers 2

5

Whenever you make a Language object, the Language object makes an Artist object.

Whenever you make an Artist object, the Artist object makes an InputReader.

Whenever you make an InputReader object, the InputReader object makes a Language.

Wash, rinse, repeat.

That's why your code fails.

The solution is simple: Stop doing that.

This code needs a bit of a redesign; what does a 'Language' object represent, and why does it make an Artist object? Why does an InputReader make a Language object?

A useful hint: Constructors can have parameters; Perhaps there should be only one InputReader and only one Language instance; in that case, have your main method make these instances, and have the InputReader constructor take a Language object (so that it doesn't have to new one up). Then have the Artist constructor also take in the Language to use instead of asking it to make a new instance of it.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks very helpful. im redesigning it currently.
i have tried it now for two hours. I am lost. can you help me?
The only way I can figure out how to help you if this answer isn't enough for you to figure it out by yourself is to teach you java from first principles. That's... not really what SO is for.
0

You have a cyclical set of constructors.

new Control() calls new Language()
new Language() calls new Artist()
new Artist() calls new InputReader()
new InputReader() calls new Language()
new Language() calls new Artist()
new Artist() calls new InputReader()
new InputReader() calls new Language()
new Language() calls new Artist()
... etc etc for infinity

Eventually, your computer runs out of stack space and you get a stack overflow.

Review the structure of your classes and break the cycle in the constructors somehow. You need to consider your object model design.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.