Problems with local variable scope. How to solve it?

后端 未结 4 1742
生来不讨喜
生来不讨喜 2020-11-28 09:23

I\'m getting the following error when trying to execute statemet.executeUpdate() in my code:

Local variable statement defined in an enclosing sc         


        
4条回答
  •  遥遥无期
    2020-11-28 09:43

    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();
                }
                ...
        });
    }
    

    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.

    Sources:

    • Anonymous Classes
    • How are Anonymous (inner) classes used in Java?

    How to solve it?

    You could...

    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;
        ...
    }
    

    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();
        }
        ...
    }
    

    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();
           }
    });
    

提交回复
热议问题