简体   繁体   English

在Java中创建对象-stackoverflow错误

[英]creating objects in java - stackoverflow error

Suppose I have two classes A and B . 假设我有两个班级AB。 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. 如果我在B类创建类A的对象,也可以创建在A类B类的对象时,它会导致堆栈溢出错误。 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. 一个解决这个问题是,我可以在B类,并且反之亦然创建的任何函数内部类A的对象,但如果我这样做,那么类A的对象创建的每个时间在其中创建类A的对象,特定功能,叫做。

Question is how can i make objects of class A and B inside each other effectively ? 问题是我如何才能使A类和B类对象彼此有效地相互融合?

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 AddRoom类

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. 请注意,我已经在AddRoom类中创建了Room类的对象,并且还在Room类中创建了AddRoom类的对象。 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. 现在,如果执行此操作,则会出现堆栈溢出错误,但是如果我在AddRoom类的任何函数中将Room类的对象作为对象,则不会显示堆栈溢出错误,并且程序可以正常运行。

You are doing with that Circle references/dependencies and that is not a good idea... 您正在使用Circle参考/依赖性,这不是一个好主意...

what you need to implement is a callback, so A can call methods from B and B can inform A see image above: 您需要实现的是回调,因此A可以从B调用方法,并且B可以通知A参见上图:

在此处输入图片说明


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

How can I make objects of class A and B inside each other effectively ? 如何有效地使A类和B类的对象相互内部?

It is NOT recommended to do this in Java (or any OOP languages) as it creates the circular dependencies. 不建议使用Java(或任何OOP语言)执行此操作,因为它会创建循环依赖项。

If not handled properly it will cause exceptions like StackOverflowError or at program/application runtime there will be exceptions while resolving the dependencies to create the objects (Exceptions will be thrown by the IOC containers like Spring, if you use). 如果处理不当,将导致诸如StackOverflowError异常,或者在程序/应用程序运行时会在解析依赖项以创建对象时发生异常(如果使用,则IOC容器(如Spring)将引发异常)。

So, even if you are managing without above issues, it is NOT at all a good practice to create circular dependencies between Java classes or packages inside the code as it will be very hard to understand/maintain and the code complexity goes high . 因此,即使您在没有上述问题的情况下进行管理, 在代码内部的Java类或包之间创建循环依赖关系也不是一个好习惯,因为这将很难理解/维护,并且代码复杂度很高 That is the reason there are code quality tools like FindBugs which help in identifying the circular dependencies so that we can avoid them during the development. 这就是为什么存在诸如FindBugs之类的代码质量工具来帮助标识循环依赖项的原因,以便我们在开发过程中避免使用它们。

You can look here for more details on the same subject. 您可以在此处查看有关同一主题的更多详细信息。

Not 100% sure what you mean, do you have classes like this?... 不确定100%的意思,您是否有类似的课程?...

public class A {
    private B b;

    public void setB(B b) {
        this.b = b;
    }
}


public class B {
    private A a;

    public void setA(A a) {
        this.a = a;
    }
}

And you want to create an "A" with a "B" in it? 您要创建一个带有“ B”的“ A”吗? For example... 例如...

public class Factory {
    public static A createA() {
        A a = new A();
        B b = new B();

        a.setB(b);
        b.setA(a);

        return a;
    }
}

Does this help? 这有帮助吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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