![](/img/trans.png)
[英]Java - How to allow all methods of a class to access an array initialized in constructor?
[英]How to use the object initialized in a constructor in other methods of the class
在這里編程新手。 我正在使用Swing,JDBC(Oracle)創建一個簡單的登錄應用程序。 它在大多數情況下都可以正常工作。 該應用程序具有3類-邏輯,UI和DBConnection。
請在此處參考整個代碼: 完整代碼
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來代替loginSuccess()和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()
方法,因為在代碼中沒有任何東西創建該方法需要作為參數的ResultSet。
正如JB Nizet解釋的那樣,您的代碼中需要進行一些更改。 嘗試以下代碼(對我有用)。
public class LoginLogic {
LoginUI lu;
public LoginLogic() {
lu = new LoginUI();
}
public LoginLogic(ResultSet rs) {
lu = new LoginUI();
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) {
/*/ Here you shld get your result rs first
con is your Connection object
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery("SELECT yourColumn FROM yourTable");
//*/
new LoginLogic(rs);
}
}
已編輯
根據我們的評論,問題在於您正在以下位置創建一個新對象:
private void getConn(String uname, String pwd) {
...
// 4. Process the result set
new LoginLogic(rs);
...
}
這意味着您沒有在if()語句中調用正確的對象。 您的新對象是使用參數化構造函數構造的,該構造函數不會初始化lu或對其進行更新。
編輯2
我認為您必須對設計進行一些更改。 我認為以下內容對您有用,但您必須處理例外情況。
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();
}
}
loginUI將更改為:
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
}
}
});
....
}
而LoginDbConn對此:
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;
}
}
希望這會有所幫助(如果是,請投票給答案)。
除了使用兩個構造函數,您還可以通過一個構造函數實現此目的:
public LoginLogic(ResultSet rs) {
lu = new LoginUI();
process(rs);
}
您只是從您要呼叫的地方撥打了此電話。 您可以通過new LoginLogic(resultSet);
來調用它new LoginLogic(resultSet);
感謝+ Guizmoo03指出了問題的根源。
如您在此代碼中看到的,該類具有2個構造函數。 創建UI時,默認構造函數首先初始化從null開始的LoginUI對象引用。
public class LoginLogic {
LoginUI lu;
public LoginLogic() {
lu = new LoginUI();
}
.....
但是,當Logic類的對象傳遞要處理的ResultSet到參數化構造函數時,將再次在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代碼中使用太多靜態元素不是一個好習慣。
因此,我切換到具有Eager初始化的Singleton模式 ,從而有效地解決了該問題。
登錄邏輯
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) {...
登錄UI
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;
}...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.