基本上我从数据库中获取ResultSet时遇到问题。错误发生在此代码块中的第34行(?)附近,但我已将其标记为
ResultSet rs = caq.executeQuery("SELECT * FROM ProjectScore"); //error goes here
我在运行时得到一个空指针异常,这是下面的catch语句的输出:
null, calculating average score failed
java.lang.NullPointerException
[Ljava.lang.StackTraceElement;@1de2b1
有趣的是,我最后在类中使用Connection完全相同,并且我没有收到任何错误。将语句复制到第一个类也不起作用,所以我认为它是另一个。我认为这就是我的全部,感谢任何帮助:)
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import javax.swing.*;
public class MainWindow extends JFrame implements ActionListener{
//.......................
private int [] averageScore;
//References
private LogInWindow liw;
private NewUserWindow nuw;
private ScoreWindow sw;
private boolean isAnotherWindowOpen = false;
private boolean isLoggedIn = false;
private ConnectionAndQueries caq;
public MainWindow(ConnectionAndQueries caq) throws SQLException{
this.caq = caq;
//.................................
//Middle
averageScore = new int [9];
calculateAverageScore();
setTable();
//............................
}
private void calculateAverageScore() throws SQLException{
try{
ResultSet rs = caq.executeQuery("SELECT * FROM ProjectScore"); //error goes here
int [] count = new int [9];
int [] totalScore = new int [9];
while(rs.next()){
int itemID = rs.getInt("itemID");
count[itemID]++;
totalScore[itemID] += rs.getInt("Score");
}
for(int i = 0; i < 9; i++){
averageScore[i] = totalScore[i] / count[i];
}
}
catch (Exception e) {
System.out.print(e.getMessage());
System.out.println(", calculating average score failed");
System.out.println(e.toString());
System.out.println(e.getStackTrace().toString());
}
}
}
//next class
import java.sql.*;
public class ConnectionAndQueries {
private static Connection connection;
private static Statement statement;
private MainWindow mw;
public ConnectionAndQueries() throws ClassNotFoundException, SQLException{
mw = new MainWindow(this);
connect();
}
public static void connect() throws ClassNotFoundException, SQLException{
try{
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://zzzzzzzzzz", "yyyy", "xxxx"); //dont think im allowed to give that info
statement = connection.createStatement();
} catch (Exception e) {
System.out.println("Connecting to the database failed");
}
}
public ResultSet executeQuery(String query) throws SQLException {
return statement.executeQuery(query);
}
public int executeUpdate(String update) throws SQLException {
return statement.executeUpdate(update);
}
public static void main(String [] args) throws ClassNotFoundException, SQLException{
ConnectionAndQueries caq = new ConnectionAndQueries();
}
}
//another class which uses the connection class, and works.
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import javax.swing.*;
public class LogInWindow extends JFrame implements ActionListener{
//........................
//References
private MainWindow mw;
private ConnectionAndQueries caq;
public LogInWindow(MainWindow mw, ConnectionAndQueries caq){
this.mw = mw;
this.caq = caq;
//......................
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == logIn){
String usn = usernameField.getText();
String pwd = passwordField.getText();
try {
ResultSet rs = caq.executeQuery("SELECT * FROM ProjectCustomer");
while(rs.next()){
if(rs.getString("username").equals(usn)){
if(rs.getString("passwrd").equals(pwd)){
logInSuccess(usn);
mw.userLoggedIn(usn);
quit();
}
}
}
if(mw.isUserLoggedIn() == false)
logInFailed();
} catch (Exception e2) {
System.out.print(e2.getMessage());
System.out.println(", error at log in");
System.out.println(e2.toString());
}
}
else if(e.getSource() == quit){
quit();
}
}
//............................
}
答案 0 :(得分:3)
当调用此构造函数时,它会将自身的引用发送给MainWindow。
public ConnectionAndQueries() throws ClassNotFoundException, SQLException{
mw = new MainWindow(this);
connect();
}
但是,由于在引用的对象尚未构造时发送此引用(即构造函数尚未完成),此时引用只能为null。
修复此问题的一种方法是将代码从构造函数移动到主方法,在 new ConnectionAndQueries()下面。但是,我强烈建议重构程序结构,将数据库连接和操作分成一个或多个单独的类,以及将UI代码与数据库代码分离。
答案 1 :(得分:2)
问题是因为构造函数。
public ConnectionAndQueries()抛出ClassNotFoundException,SQLException {
mw = new MainWindow(this);
连接();
}
这里是Mainwindow的构造函数,它对calculateAverageScore的makding调用,它正在使用ConnectionAndQueries执行查询。由于到目前为止还没有调用connect(),因此connection和statement为null。因此得到空指针异常。
尝试在mw = new MainWindow(this)之前调用connect();言。
public ConnectionAndQueries()抛出ClassNotFoundException,SQLException {
连接();
mw = new MainWindow(this);
}
但是,确保Gorkamorka建议的代码重构是必需的。
答案 2 :(得分:1)
看起来您的ConnectionAndQuery
对象为空。
我会在构造时检查这是否为零,而不是在你尝试使用它时。这将更早地捕获错误(并且在更有用的时间)。这也是可能的(因为错误报告不清楚 - 见下文):
catch (Exception e) {
System.out.println("Connecting to the database failed");
}
正在捕获错误,但保留语句对象未初始化(null)。我会检查语句的nullness作为前提条件,或者更好地仍然抛出该原始异常,以便客户端代码必须处理损坏的ConnectionAndQuery
对象。
此
System.out.println(e.getStackTrace().toString());
不是很有帮助,顺便说一下。我宁愿这样做:
e.printStackTrace();
因为它将转储完整的堆栈跟踪,并将其转储到stderr
(传统的错误目标)。目前你正在堆栈帧数组上调用toString()
,这实际上没有任何用处。