2016-11-21 98 views
0

假设我有两个类AB。如果我在B类创建类A的一个对象,并且还在A类创建类B的对象,它会导致堆栈溢出错误。一个解决这个问题是,我可以创建在B类,并且反之亦然的任何函数内部类A的目的,但如果我这样做,那么类的对象A创建每次该特定功能,其中类的对象A被创建,被调用。在java中创建对象 - stackoverflow错误

问题是我怎样才能使对象内部有效地彼此相对?AB

考虑下面的例子。

我创建房类的对象AddRoom类又创造AddRoom类的对象室教室类

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类的对象,然后堆栈溢出错误不显示和程序运行良好。

+0

您可能想要将现有实例传递给其他类。 – SLaks

+0

您不在这些类中创建任何对象。该代码不会导致堆栈溢出。 – Kayaman

+0

@Kayaman我发布了一个代码示例,它给了我堆栈溢出错误。 – Yousaf

回答

1

您与该圈的引用/依赖这样做,这是不是一个好主意......

您需要实现的是一个回调,因此可以调用从B和B方法可以通知一看图像以上:

enter image description here


实施例:

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

明白你的意思,你有类这样不是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; 
    } 
} 

你想创建一个“A”与它“B”?例如...

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

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

     return a; 
    } 
} 

这是否对您有帮助?

+0

我编辑了我的问题。我希望它能帮助你理解我想问的问题。 – Yousaf

1

如何使A和B级的物体有效地相互嵌入 ?

不建议在Java(或任何OOP语言)中执行此操作,因为它会创建循环依赖关系。

如果处理不当会导致异常,如StackOverflowError,或者在程序/应用程序运行时,在解析依赖项以创建对象时会出现异常(如果使用的话,IOC容器会抛出异常)。

因此,即使您正在管理没有以上问题,在代码内部创建Java类或包之间的循环依赖关系并不是一个好习惯,因为它很难理解/维护并且代码复杂度去高。这就是存在代码质量工具(如FindBugs)的原因,这些工具有助于识别循环依赖关系,以便在开发期间避免它们。

有关同一主题的更多详细信息,您可以查看here