Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在类的其他方法中使用构造函数中初始化的对象_Java_Swing_Object_Constructor - Fatal编程技术网

Java 如何在类的其他方法中使用构造函数中初始化的对象

Java 如何在类的其他方法中使用构造函数中初始化的对象,java,swing,object,constructor,Java,Swing,Object,Constructor,这里是编程新手。我正在使用Swing、JDBC(Oracle)创建一个简单的登录应用程序。它在大部分情况下都能正常工作。该应用程序有3个类-逻辑、用户界面和数据库连接 请参阅此处的全部代码: 1。LoginLogic.java public class LoginLogic { LoginUI lu; public LoginLogic() { lu = new LoginUI(); } public LoginLogic(Resu

这里是编程新手。我正在使用Swing、JDBC(Oracle)创建一个简单的登录应用程序。它在大部分情况下都能正常工作。该应用程序有3个类-逻辑、用户界面和数据库连接

请参阅此处的全部代码:

1。LoginLogic.java

    public class LoginLogic {

    LoginUI lu;

    public LoginLogic() {
        lu = new LoginUI();

    }

    public LoginLogic(ResultSet rs) {
        process(rs);
    }

    private void process(ResultSet rs) {
        try {
            if (rs.next()) {
                lu.loginSuccess();

            } else {
                lu.loginFailed();
            }
        } catch (SQLException e) {
            // TODO: handle exception
        }
    }

    public static void main(String[] args) {

        new LoginLogic();

    }


 }
最初,我直接显示了一个JOptionPane来代替loginsAccess()和loginFailed()方法,它按预期工作。但是我想把所有的UI功能委托给UI类,所以我在UI类中创建了这两个方法

void loginSuccess() {
        JOptionPane.showMessageDialog(null, "Login Successful!");
}

void loginFailed() {
    JOptionPane.showMessageDialog(null, "Login Failed!");
} 
但是这些方法不会使用我在构造函数中创建的UI对象来调用。没有错误,但也没有JOptionPane


如何在process()方法中使用UI对象引用lu调用UI类的方法?

主方法调用无参数构造函数。此无参数构造函数实现为

lu = new LoginUI();
因此,它创建了LoginUI对象,但不做更多的事情。特别是,它从不调用
process()
方法,该方法显示JOptionPane

另一个从未调用过的构造函数确实调用了
process()
方法。但它不会初始化LoginUI对象


我也不知道如何调用
process()
方法,因为代码中没有创建此方法需要作为参数的结果集的内容。

您的主方法调用无参数构造函数。此无参数构造函数实现为

lu = new LoginUI();
因此,它创建了LoginUI对象,但不做更多的事情。特别是,它从不调用
process()
方法,该方法显示JOptionPane

另一个从未调用过的构造函数确实调用了
process()
方法。但它不会初始化LoginUI对象


我也不知道如何调用
process()
方法,因为代码中没有创建此方法需要作为参数的结果集的内容。

不使用两个构造函数,您可以通过一个构造函数实现这一点:

public LoginLogic(ResultSet rs) {
    lu = new LoginUI();
    process(rs);
}

你刚从你想打电话的地方打过来。您可以通过
newloginlogic(resultSet)调用它

不使用两个构造函数,您可以通过一个构造函数实现这一点:

public LoginLogic(ResultSet rs) {
    lu = new LoginUI();
    process(rs);
}

你刚从你想打电话的地方打过来。您可以通过
newloginlogic(resultSet)调用它

正如JB Nizet所解释的,您的代码中需要做一些更改。试试下面的代码(它对我有用)

已编辑

根据我们的评论,问题在于您正在您的系统中创建一个新对象:

 private void getConn(String uname, String pwd) {
    ...
        // 4. Process the result set
        new LoginLogic(rs);

    ...

}
这意味着您没有在if()语句中调用正确的对象。您的新对象是使用参数化构造函数构造的,该构造函数不初始化lu或更新它

EDITED2

我想你得改变一下你的设计。我认为以下几点对你有用,但你必须处理例外情况

public class LoginLogic {

LoginUI lu;

public LoginLogic() {
    lu = new LoginUI();

}


public void process() {
    try {
        if (lu.getRs().next()) {
            lu.loginSuccess();

        } else {
            lu.loginFailed();
        }
    } catch (SQLException e) {
        // TODO: handle exception
    }
}

public static void main(String[] args) {

    LoginLogic loginLogic = new LoginLogic();
    loginLogic.process();
 }
 }
登录名将更改为:

public class LoginUI {

      ...
       ResultSet rs;

       public ResultSet getRs() {
          return rs;
       }
       ...
      btnLogin.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            try {
                String uname = tfUname.getText().trim();
                String pwd = tfPwd.getText().trim();

                LoginDbConn loginDbConn = new LoginDbConn(uname, pwd);// startDB after user presses     
                rs = loginDbConn.getConn();

            } catch (Exception ex) {
                // TODO: handle exception
            }

        }
    });

    ....
 }
并将登录名设置为:

 public class LoginDbConn {

String uname;
String pwd;
ResultSet rs;
/*
 * public LoginDbConn() { // TODO Auto-generated constructor stub }
 */

public LoginDbConn(String uname, String pwd) {
    this.uname = uname;
    this.pwd = pwd;
}

public ResultSet getConn() {
    try {
        // 0. Register the JDBC drivers
        String driverClass = "oracle.jdbc.driver.OracleDriver";
        Class.forName(driverClass);
        // or DriverManager.registerDriver(new oracle.jdbc.OracleDriver());

        // 1. Get a connection to the Database
        String dbUrl = "jdbc:oracle:thin:@localhost:1521:xe";
        String dbuname = "scott";
        String dbpwd = "tiger";
        Connection conn = DriverManager.getConnection(dbUrl, dbuname, dbpwd);

        // 2. Create a statement
        // String sql = "SELECT * FROM users WHERE name = '"+uname+"' and
        // password = '"+pwd+"'";
        // Statement st = conn.createStatement();
        String sql = "select * from users where name = ? and password = ?";
        PreparedStatement pst = conn.prepareStatement(sql);

        pst.setString(1, uname);
        pst.setString(2, pwd);

        // 3. Execute SQL query
        rs = pst.executeQuery();

        // 5. Close Connection
        // conn.close();

        return rs;
    } catch (SQLException | ClassNotFoundException e) {

            // THIS EXCEPTION MUST ABSOLUTELY BE HANDLED
    }
    return rs;
}
}


希望这会有所帮助(如果有,请投票支持答案)。

正如JB Nizet所解释的,您的代码中有一些更改需要完成。试试下面的代码(它对我有用)

已编辑

根据我们的评论,问题在于您正在您的系统中创建一个新对象:

 private void getConn(String uname, String pwd) {
    ...
        // 4. Process the result set
        new LoginLogic(rs);

    ...

}
这意味着您没有在if()语句中调用正确的对象。您的新对象是使用参数化构造函数构造的,该构造函数不初始化lu或更新它

EDITED2

我想你得改变一下你的设计。我认为以下几点对你有用,但你必须处理例外情况

public class LoginLogic {

LoginUI lu;

public LoginLogic() {
    lu = new LoginUI();

}


public void process() {
    try {
        if (lu.getRs().next()) {
            lu.loginSuccess();

        } else {
            lu.loginFailed();
        }
    } catch (SQLException e) {
        // TODO: handle exception
    }
}

public static void main(String[] args) {

    LoginLogic loginLogic = new LoginLogic();
    loginLogic.process();
 }
 }
登录名将更改为:

public class LoginUI {

      ...
       ResultSet rs;

       public ResultSet getRs() {
          return rs;
       }
       ...
      btnLogin.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {

            try {
                String uname = tfUname.getText().trim();
                String pwd = tfPwd.getText().trim();

                LoginDbConn loginDbConn = new LoginDbConn(uname, pwd);// startDB after user presses     
                rs = loginDbConn.getConn();

            } catch (Exception ex) {
                // TODO: handle exception
            }

        }
    });

    ....
 }
并将登录名设置为:

 public class LoginDbConn {

String uname;
String pwd;
ResultSet rs;
/*
 * public LoginDbConn() { // TODO Auto-generated constructor stub }
 */

public LoginDbConn(String uname, String pwd) {
    this.uname = uname;
    this.pwd = pwd;
}

public ResultSet getConn() {
    try {
        // 0. Register the JDBC drivers
        String driverClass = "oracle.jdbc.driver.OracleDriver";
        Class.forName(driverClass);
        // or DriverManager.registerDriver(new oracle.jdbc.OracleDriver());

        // 1. Get a connection to the Database
        String dbUrl = "jdbc:oracle:thin:@localhost:1521:xe";
        String dbuname = "scott";
        String dbpwd = "tiger";
        Connection conn = DriverManager.getConnection(dbUrl, dbuname, dbpwd);

        // 2. Create a statement
        // String sql = "SELECT * FROM users WHERE name = '"+uname+"' and
        // password = '"+pwd+"'";
        // Statement st = conn.createStatement();
        String sql = "select * from users where name = ? and password = ?";
        PreparedStatement pst = conn.prepareStatement(sql);

        pst.setString(1, uname);
        pst.setString(2, pwd);

        // 3. Execute SQL query
        rs = pst.executeQuery();

        // 5. Close Connection
        // conn.close();

        return rs;
    } catch (SQLException | ClassNotFoundException e) {

            // THIS EXCEPTION MUST ABSOLUTELY BE HANDLED
    }
    return rs;
}
}

希望这会有所帮助(如果有,请投票支持答案)。

感谢您指出问题的根源

正如您在这段代码中看到的,这个类有2个构造函数。创建UI时,默认构造函数首先初始化以null开头的LoginUI对象引用

public class LoginLogic {

    LoginUI lu;

    public LoginLogic() {
        lu = new LoginUI();

    }
     .....
但是,当逻辑类的对象将要处理的结果集传递给参数化构造函数时,它会在DbConn类中再次创建逻辑类的对象。此实例化取消引用UI对象变量lu。因此,正如我在最初的问题中指出的,它不能再用于访问process()方法中UI类的方法

...

LoginUI lu;

...

public LoginLogic(ResultSet rs) {
        process(rs);
    }

    private void process(ResultSet rs) {
        try {
            if (rs.next()) {
                lu.loginSuccess();

            } else {
                lu.loginFailed();
            }
        } catch (SQLException e) {
            // TODO: handle exception
        }
    }
...
DbConn类代码段

// 4. Process the result set
   new LoginLogic(rs);
因此解决方案: 一种可能的解决方法是在构造函数外部实例化UI对象变量lu

...
LoginUI lu = new LoginUI();

public LoginLogic() {

}

public LoginLogic(ResultSet rs) {
    process(rs);
}

private void process(ResultSet rs) {
...
虽然这解决了解引用问题,但当DbConn创建逻辑类的新对象时,它导致GUI重新初始化

public class LoginUI {

        // Container declarations
        ...

        // Component declarations
       ...

        public LoginUI() {
            createFrame();
        }

        private void createFrame() {
        ...
另一种实际上没有太多副作用的解决方法是使用静态方法。但是在OO代码中使用太多的静态元素不是一个好的实践

因此,我切换到,这有效地解决了问题

LoginLogic

public class LoginLogic {

    static final LoginUI lu = LoginUI.getInstance(); // immutable singleton
                                                        // object reference

    public LoginLogic() {
        // TODO Auto-generated constructor stub
    }

    public LoginLogic(ResultSet rs) { // parameterized constructor
        process(rs);
    }

    void process(ResultSet rs) {...
LoginUI

public class LoginUI {

    // Container declarations

    // Component declarations

    private static final LoginUI lu = new LoginUI(); // immutable singleton
                                                        // object

    private LoginUI() { // prevent external instantiation
        initUI();
    }

    static LoginUI getInstance() { // getter for the singleton object
        return lu;
    }...
感谢您指出了问题的根源

正如您在这段代码中看到的,这个类有2个构造函数。创建UI时,默认构造函数首先初始化以null开头的LoginUI对象引用

public class LoginLogic {

    LoginUI lu;

    public LoginLogic() {
        lu = new LoginUI();

    }
     .....
但是,当逻辑类的对象将要处理的结果集传递给参数化构造函数时,它会在DbConn类中再次创建逻辑类的对象。此实例化取消引用UI对象变量lu。因此,正如我在最初的问题中指出的,它不能再用于访问process()方法中UI类的方法

...

LoginUI lu;

...

public LoginLogic(ResultSet rs) {
        process(rs);
    }

    private void process(ResultSet rs) {
        try {
            if (rs.next()) {
                lu.loginSuccess();

            } else {
                lu.loginFailed();
            }
        } catch (SQLException e) {
            // TODO: handle exception
        }
    }
...
DbConn类代码段

// 4. Process the result set
   new LoginLogic(rs);
因此解决方案: 一种可能的解决方法是实例化UI对象变量