局部变量范围的问题。怎么解决? [英] 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.
这是我到目前为止的代码:
This is my code so far:
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");
}
}
我也尝试设置声明
final但声明给了我另一个错误。
I also tried to set statement
final but the declaration gives me another error.
推荐答案
你有一个范围确实存在问题,因为语句
是这里定义的本地方法变量:
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
(由于代码不可能)或声明为类成员,因此内部类可以访问此语句
变量。
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.
来源:
- Anonymous Classes
- How are Anonymous (inner) classes used in Java?
使语句
成员而不是本地变量:
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
按钮之后才会被使用,那么创建连接是没有意义的之前这实际发生了。你可以使用这样的所有局部变量:
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屋!