简体   繁体   中英

Stack overflow error while invoking toString method

this is my code but when I execute the program I get many errors and I don't know why. May anyone help me?

RegisteredUser.java

public class RegisteredUser {
    private String nickname;
    ArrayList<ReviewDAO> reviews;

    public RegisteredUser(String nickname) {
        this.nickname = nickname;
        reviews = new ArrayList<>();
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public void addReview(ReviewDAO review) {
        if (!this.reviews.contains(review)) {
            this.reviews.add(review);
            review.addRegisteredUser(this);
        }
    }

    @Override
    public String toString() {
        return "RegisteredUser{" +
                "nickname='" + nickname + '\'' +
                ", reviews=" + reviews +
                '}';
    }
}

ReviewDAO.java

public abstract class ReviewDAO {
    RegisteredUser registeredUser;

    public abstract boolean write(Review review);

    public void addRegisteredUser(RegisteredUser registeredUser) {
        this.registeredUser = registeredUser;
    }

    @Override
    public String toString() {
        return "ReviewDAO{" +
                "registeredUser=" + registeredUser +
                '}';
    }
}

Review.java

public class Review {
    private String title;
    private String description;
    private int rank;
    private boolean isAnonymous;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public boolean isAnonymous() {
        return isAnonymous;
    }

    public void setAnonymous(boolean anonymous) {
        isAnonymous = anonymous;
    }
}

ReviewDAO_MongoDB.java

public class ReviewDAO_MongoDB extends ReviewDAO {
    @Override
    public boolean write(Review review) {
        return false;
        // todo
    }
}

ReviewDAO_Factory.java

public class ReviewDAO_Factory {

    public ReviewDAO getReviewDAO(String technology) throws ExecutionControl.NotImplementedException {
        if (technology.equals("mongodb"))
            return new ReviewDAO_MongoDB();
        else
            throw new ExecutionControl.NotImplementedException("");
    }
}

BusinessLogic.java

public class BusinessLogic {
    public static void main(String[] args) throws ExecutionControl.NotImplementedException {
        ReviewDAO_Factory reviewDAO_factory = new ReviewDAO_Factory();
        RegisteredUser registeredUser = new RegisteredUser("Alessandro");

        registeredUser.addReview(reviewDAO_factory.getReviewDAO("mongodb"));
        System.out.println(registeredUser.toString());
    }
}

I am getting

Exception in thread "main" java.lang.StackOverflowError at RegisteredUser.toString(RegisteredUser.java:33) at java.base/java.lang.String.valueOf(String.java:2951) at ReviewDAO.toString(ReviewDAO.java:15)...

Process finished with exit code 1

errors

First of all, the design looks faulty. You should never mix POJOs with DAOs. DAOs are "data access object" classes which deals with CRUD operations on the POJOs. Here you have 2 POJOs - Review and RegisteredUser. It's the responsibility of ReviewDAO to perform CRUD operations on managed/unmanaged instances (or entities) of Review. And for RegisteredUser also you need another POJO probably (in your actual code).

Secondly, I see you are calling List contains method to check if the user already has given that review, yet you have not implemented "equals" and "hashCode" in the ReviewDAO .

public void addReview(ReviewDAO review) {
        if (!this.reviews.contains(review)) {
            this.reviews.add(review);
            review.addRegisteredUser(this);
        }
    }

I have made few tweaks. Please check if it satisfies your need:

RegisteredUser class (Have used hashset cause "contains" search will be faster)

public class RegisteredUser {
  private String nickname;
  private Set<Review> reviews;

  public RegisteredUser(String nickname) {
    this.nickname = nickname;
    reviews = new HashSet<>();
  }

  public String getNickname() {
    return nickname;
  }

  public void setNickname(String nickname) {
    this.nickname = nickname;
  }

  public void addReview(Review review) {
    if (!this.reviews.contains(review)) {
      this.reviews.add(review);
      //review.addRegisteredUser(this);
    }
  }

  @Override
  public String toString() {
    return "RegisteredUser{" +
        "nickname='" + nickname + '\'' +
        ", reviews=" + reviews +
        '}';
  }
}

ReviewDAO class :

public abstract class ReviewDAO {
  private RegisteredUser registeredUser;

  public abstract boolean write(Review review);

  public void addRegisteredUser(RegisteredUser registeredUser) {
    this.registeredUser = registeredUser;
  }

}

Review class :

public class Review {
  private String title;
  private String description;
  private int rank;
  private boolean isAnonymous;

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public int getRank() {
    return rank;
  }

  public void setRank(int rank) {
    this.rank = rank;
  }

  public boolean isAnonymous() {
    return isAnonymous;
  }

  public void setAnonymous(boolean anonymous) {
    isAnonymous = anonymous;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o)
      return true;
    if (o == null || getClass() != o.getClass())
      return false;
    Review review = (Review) o;
    return Objects.equals(title, review.title);
  }

  @Override
  public int hashCode() {
    return Objects.hash(title);
  }
}

BusinessLogic class

public class BusinessLogic {
  public static void main(String[] args) throws ExecutionControl.NotImplementedException {
    ReviewDAO_Factory reviewDAO_factory = new ReviewDAO_Factory();

    RegisteredUser registeredUser = new RegisteredUser("Alessandro");

    Review review = new Review();
    review.setTitle("some review");
    review.setDescription("some desc");

    registeredUser.addReview(review);

    ReviewDAO reviewDAO = reviewDAO_factory.getReviewDAO("mongodb");
    reviewDAO.addRegisteredUser(registeredUser);

    System.out.println(registeredUser.toString());
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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