局部变量作用域的问题.如何解决? [英] Problems with local variable scope. How to solve it?
问题描述
尝试在我的代码中执行 statemet.executeUpdate()
时出现以下错误:
I'm getting the following error when trying to execute statemet.executeUpdate()
in my code:
Local variable statement defined in an enclosing scope must be final or effectively final.
这是我目前的代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;.
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class a1 {
protected Shell shell;
private Text text;
private Text text_1;
private Text text_2;
private Text text_3;
/**
* Launch the application.
* @param args
*/
public static void main(String[] args) {
try {
a1 window = new a1();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Open the window.
*/
public void open() {
Display display = Display.getDefault();
createContents();
shell.open();
shell.layout();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
/**
* Create contents of the window.
*/
protected void createContents() {
Connection connect = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
connect = DriverManager.getConnection("jdbc:mysql://localhost/railwaydb", "root", "");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Statement statement = null;
// statements allow to issue SQL queries to the database
try {
statement = connect.createStatement();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
shell = new Shell();
shell.setSize(450, 300);
shell.setText("SWT Application");
Label lblName = new Label(shell, SWT.NONE);
lblName.setBounds(10, 43, 47, 15);
lblName.setText("Name");
Label lblFrom = new Label(shell, SWT.NONE);
lblFrom.setBounds(10, 74, 55, 15);
lblFrom.setText("From");
Label lblTo = new Label(shell, SWT.NONE);
lblTo.setBounds(10, 105, 55, 15);
lblTo.setText("To");
Label lblPrice = new Label(shell, SWT.NONE);
lblPrice.setBounds(10, 137, 55, 15);
lblPrice.setText("Price");
text = new Text(shell, SWT.BORDER);
text.setBounds(64, 43, 76, 21);
text_1 = new Text(shell, SWT.BORDER);
text_1.setBounds(64, 74, 76, 21);
text_2 = new Text(shell, SWT.BORDER);
text_2.setBounds(64, 105, 76, 21);
text_3 = new Text(shell, SWT.BORDER);
text_3.setBounds(64, 137, 76, 21);
Label lblRailwayDatabase = new Label(shell, SWT.NONE);
lblRailwayDatabase.setBounds(174, 10, 97, 15);
lblRailwayDatabase.setText("Railway Database");
Label lblCreateView = new Label(shell, SWT.NONE);
lblCreateView.setBounds(189, 43, 76, 15);
lblCreateView.setText("Create View");
Button btnName = new Button(shell, SWT.CHECK);
btnName.setBounds(189, 73, 93, 16);
btnName.setText("Name");
Button btnFrom = new Button(shell, SWT.CHECK);
btnFrom.setBounds(189, 105, 93, 16);
btnFrom.setText("From");
Button btnTo = new Button(shell, SWT.CHECK);
btnTo.setBounds(189, 137, 93, 16);
btnTo.setText("To");
Button btnPrice = new Button(shell, SWT.CHECK);
btnPrice.setBounds(189, 171, 93, 16);
btnPrice.setText("Price");
Button btnInsert = new Button(shell, SWT.NONE);
btnInsert.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
String name = text.getText();
String from = text_1.getText();
String to = text_2.getText();
String price = text_3.getText();
String query = "INSERT INTO booking (name, fromst, tost, price) VALUES ('"+name+"', '"+from+"', '"+to+"', '"+price+"')";
try {
statement.executeUpdate(query);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
btnInsert.setBounds(10, 171, 75, 25);
btnInsert.setText("Insert");
Button btnView = new Button(shell, SWT.NONE);
btnView.setBounds(307, 74, 75, 25);
btnView.setText("View");
Button btnIndex = new Button(shell, SWT.NONE);
btnIndex.setBounds(307, 127, 75, 25);
btnIndex.setText("Index");
}
}
我也尝试将 statement
设置为 final,但声明给了我另一个错误.
I also tried to set statement
final but the declaration gives me another error.
推荐答案
您确实存在范围问题,因为 statement
是此处定义的本地方法变量:
You have a scope problem indeed, because statement
is a local method variable defined here:
protected void createContents() {
...
Statement statement = null; // local variable
...
btnInsert.addMouseListener(new MouseAdapter() { // anonymous inner class
@Override
public void mouseDown(MouseEvent e) {
...
try {
statement.executeUpdate(query); // local variable out of scope here
} catch (SQLException e1) {
e1.printStackTrace();
}
...
});
}
当您尝试在 mouseDown()
方法中访问此变量时,您是在尝试从匿名内部类中访问局部变量,但范围不够.所以它绝对必须是 final
(这给你的代码是不可能的)或声明为类成员,以便内部类可以访问这个 statement
变量.
When you try to access this variable inside mouseDown()
method you are trying to access a local variable from within an anonymous inner class and the scope is not enough. So it definitely must be final
(which given your code is not possible) or declared as a class member so the inner class can access this statement
variable.
来源:
使 statement
成为类成员而不是局部变量:
Make statement
a class member instead of a local variable:
public class A1 { // Note Java Code Convention, also class name should be meaningful
private Statement statement;
...
}
你可以...
按照@HotLicks 的建议,定义另一个最终变量并改用这个变量:
You could...
Define another final variable and use this one instead, as suggested by @HotLicks:
protected void createContents() {
...
Statement statement = null;
try {
statement = connect.createStatement();
final Statement innerStatement = statement;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
...
}
但是你应该...
重新考虑您的方法.如果在按下 btnInsert
按钮之前不会使用 statement
变量,那么在这种情况实际发生之前创建连接是没有意义的..您可以像这样使用所有局部变量:
But you should...
Reconsider your approach. If statement
variable won't be used until btnInsert
button is pressed then it doesn't make sense to create a connection before this actually happens. You could use all local variables like this:
btnInsert.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
try {
Class.forName("com.mysql.jdbc.Driver");
try (Connection connect = DriverManager.getConnection(...);
Statement statement = connect.createStatement()) {
// execute the statement here
} catch (SQLException ex) {
ex.printStackTrace();
}
} catch (ClassNotFoundException ex) {
e.printStackTrace();
}
});
这篇关于局部变量作用域的问题.如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!