簡體   English   中英

在Java中創建對象-stackoverflow錯誤

[英]creating objects in java - stackoverflow error

假設我有兩個班級AB。 如果我在B類創建類A的對象,也可以創建在A類B類的對象時,它會導致堆棧溢出錯誤。 一個解決這個問題是,我可以在B類,並且反之亦然創建的任何函數內部類A的對象,但如果我這樣做,那么類A的對象創建的每個時間在其中創建類A的對象,特定功能,叫做。

問題是我如何才能使A類和B類對象彼此有效地相互融合?

考慮下面的例子。

房間等級

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類

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                   
}

請注意,我已經在AddRoom類中創建了Room類的對象,並且還在Room類中創建了AddRoom類的對象。 現在,如果執行此操作,則會出現堆棧溢出錯誤,但是如果我在AddRoom類的任何函數中將Room類的對象作為對象,則不會顯示堆棧溢出錯誤,並且程序可以正常運行。

您正在使用Circle參考/依賴性,這不是一個好主意...

您需要實現的是回調,因此A可以從B調用方法,並且B可以通知A參見上圖:

在此處輸入圖片說明


例:

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

如何有效地使A類和B類的對象相互內部?

不建議使用Java(或任何OOP語言)執行此操作,因為它會創建循環依賴項。

如果處理不當,將導致諸如StackOverflowError異常,或者在程序/應用程序運行時會在解析依賴項以創建對象時發生異常(如果使用,則IOC容器(如Spring)將引發異常)。

因此,即使您在沒有上述問題的情況下進行管理, 在代碼內部的Java類或包之間創建循環依賴關系也不是一個好習慣,因為這將很難理解/維護,並且代碼復雜度很高 這就是為什么存在諸如FindBugs之類的代碼質量工具來幫助標識循環依賴項的原因,以便我們在開發過程中避免使用它們。

您可以在此處查看有關同一主題的更多詳細信息。

不確定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;
    }
}

您要創建一個帶有“ B”的“ A”嗎? 例如...

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

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

        return a;
    }
}

這有幫助嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM