Yousaf Yousaf - 10 months ago 34
Java Question

creating objects in java - stackoverflow error

Suppose I have two classes A and B. If i create an object of class A in class B and also create object of class B in class A, it causes Stack Overflow error. One solution to this problem is that i can create an object of class A inside any function in class B and vice versa but if I do this then object of class A is created every time that particular function in which object of class A is created, is called.

Question is how can i make objects of class A and B inside each other effectively ?

Consider following example.

Room Class

public class Room {

String roomno;
String reserved;
String category;
String airconditioned;
String bedtype;
String rent;

Connection con;
PreparedStatement ps;
ResultSet rs;

AddRoom adr = new AddRoom();
RemoveRoom rr = new RemoveRoom();
UpdateRoom ur = new UpdateRoom();
// AllRooms alr = new AllRooms();

public Room()
{
roomno = "";
reserved = "";
category = "";
airconditioned = "";
bedtype = "";
rent = "";
make_connection();
}

public void make_connection()
{
try{
String driver = "net.ucanaccess.jdbc.UcanaccessDriver";
Class.forName(driver);
String login = "jdbc:ucanaccess://C:\\MsDatabase\\EmployeeDB.accdb";
con = DriverManager.getConnection(login);

}catch(Exception ex){ System.out.println(ex);}
}

public void add_room(AddRoom obj)
{
try{
adr = obj;
if("".equals(adr.get_jtextfield1().getText())||"".equals(adr.get_jtextfield2().getText())||
"".equals(adr.get_jtextfield3().getText())||"".equals(adr.get_jtextfield4().getText())||
"".equals(adr.get_jtextfield5().getText())||"".equals(adr.get_jtextfield6().getText()))
{
JOptionPane.showMessageDialog(null, "None of the fields can be left empty");
}
else
{
roomno = adr.get_jtextfield1().getText();
reserved = adr.get_jtextfield2().getText();
category = adr.get_jtextfield3().getText();
airconditioned = adr.get_jtextfield4().getText();
bedtype = adr.get_jtextfield5().getText();
rent = adr.get_jtextfield6().getText();

String sql = "INSERT INTO RoomInfo(RoomNumber,Reserved,RoomCategory,AirConditioned,BedType,RentPerDay)"
+ "VALUES(?,?,?,?,?,?)";

ps = con.prepareStatement(sql);

ps.setInt(1, new Integer(roomno));
ps.setString(2, reserved);
ps.setString(3, category);
ps.setString(4, airconditioned);
ps.setString(5, bedtype);
ps.setInt(6, new Integer(rent));
ps.executeUpdate();
JOptionPane.showMessageDialog(null, "Room Added Successfully");
}

}catch(Exception ex){
JOptionPane.showMessageDialog(null, "Input in Room Number and "
+ "Rent Per Day should be a number");
}
}

}


AddRoom Class

public class AddRoom extends javax.swing.JFrame {

Room objr = new Room();
public AddRoom() {
initComponents();
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//Room objr = new Room();
objr.add_room(this);
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
AdminHome admh = new AdminHome();
admh.setVisible(true);
dispose();
}

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new AddRoom().setVisible(true);
}
});
}

public JTextField get_jtextfield1()
{
return jTextField1;
}

public JTextField get_jtextfield2()
{
return jTextField2;
}

public JTextField get_jtextfield3()
{
return jTextField3;
}

public JTextField get_jtextfield4()
{
return jTextField4;
}

public JTextField get_jtextfield5()
{
return jTextField5;
}
public JTextField get_jtextfield6()
{
return jTextField6;
}

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JLabel jLabel7;
private javax.swing.JPanel jPanel1;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
private javax.swing.JTextField jTextField5;
private javax.swing.JTextField jTextField6;
// End of variables declaration
}


Note that i have created object of Room class in AddRoom class and also created object of AddRoom class in Room class. Now if i do this then i get stack overflow error but if if i make object of Room class inside any function in AddRoom class then stack overflow error is not displayed and program runs fine.

Answer Source

You are doing with that Circle references/dependencies and that is not a good idea...

what you need to implement is a callback, so A can call methods from B and B can inform A see image above:

enter image description here


Example:

//Interface
public interface ICallback{
    void onMessage(String msg);
}

//the class A call methods from B
public class A implements ICallback{

    private B b;

    public A(){
        b= new B();
        b.setCallback(this);
        b.printSomething(5);
        b.printSomething(0);
    }
    @Override
    public void onMessage(String msg){
    }
}

//the Class B can communicate to A with the callback
public class B {
    private ICallback cb;
    public B(){
    }
    public void setCallback(ICallback cb){
        this.cb = cb;
    }
    public void printSomething(int i){
        if(i==0){
            cb.onMessage("this is zero");
        }
    }
}