Как я могу использовать прослушиватель действий для изменения / проверки переменной за пределами слушателя в Java? [Дубликат]

Ниже приведена функция изменения URL-адреса без перезагрузки страницы. Он поддерживает только функцию HTML5

  ChangeUrl (page, url) {if (typeof (history.pushState)! = "Undefined") {var obj = {Страница: page, Url: url}  ;  history.pushState (obj, obj.Page, obj.Url);  } else {window.location.href = "homePage";  // alert ("Браузер не поддерживает HTML5.");  }} ChangeUrl ('Страница1', 'homePage');   
33
задан dic19 17 September 2014 в 16:40
поделиться

4 ответа

У вас действительно проблема с областью видимости, потому что statement - это локальная переменная метода, определенная здесь:

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.

Источники:


Как его решить?

Вы могли бы ...

Сделать statement членом класса вместо локальной переменной:

public class A1 { // Note Java Code Convention, also class name should be meaningful   
    private Statement statement;
    ...
}

Вы может ...

Определить другую конечную переменную и использовать ее вместо этого, как было предложено @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();
    }
    ...
}

Но вы должны ...

Пересмотрите свой подход. Если переменная statement не будет использоваться до тех пор, пока не будет нажата кнопка btnInsert, это не имеет смысла создавать соединение перед , это действительно происходит. Вы можете использовать все локальные переменные следующим образом:

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();
       }
});
58
ответ дан Community 17 August 2018 в 11:21
поделиться
  • 1
    Обратите внимание, что простое решение состоит в том, чтобы добавить оператор, подобный final Statement innerStatement = statement;, и обратиться к innerStatement внутри mouseDown. – Hot Licks 17 September 2014 в 17:06
  • 2
    Благодарю вас. @hot лижет, но я получаю это предупреждение: нулевой указатель доступа: переменная innerstatement может быть только нулевой в этом месте – Amit Chahar 17 September 2014 в 17:06
  • 3
    @amitsingh - потому что вы разместили его до statement. – Hot Licks 17 September 2014 в 17:17
  • 4
    @amitsingh, пожалуйста, см. мое редактирование. Надеюсь, поможет. – dic19 17 September 2014 в 20:57

Существует также третье решение этой проблемы, отличное от того, чтобы сделать его окончательным или объявить недоступную переменную в качестве члена класса, поскольку эти параметры не всегда возможны или желательны.

Во-первых, мы просто НЕ МОЖЕМ сделать переменную окончательной, поскольку ее состояние может меняться во время запуска программы, и наши решения внутри внутреннего переопределения класса могут зависеть от его текущего состояния.

Во-вторых, хорошая практика объектно-ориентированного программирования предполагает использование только переменных / константы, которые являются жизненно важными для определения класса как членов класса. Это означает, что если переменная, на которую мы ссылаемся внутри анонимного переопределения внутреннего класса, является просто переменной утилиты, то она не должна быть указана среди членов класса.

Итак - с Java 8 - теперь мы имеем третий вариант, описанный здесь:

https://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

Начиная с Java SE 8, если вы объявляете локальный класс в методе, он может получить доступ к параметрам метода.

Итак, теперь мы можем просто поместить код, содержащий новый внутренний класс & amp; его метод переопределяется в частный статический метод, параметры которого включают переменную, которую мы вызываем изнутри переопределения. Этот статический метод вызывается после утверждения объявления btnInsert: -

 // Original code :
 Button btnInsert = new Button(shell, SWT.NONE);
 // Call to new private static method :
 addMouseListener(Button btnInsert, Statement statement);

 . . . 
 . . .
 . . . 

 // New private static method to give access to query statement :
 private static void addMouseListener(Button btn, Statement st)
 {
    btn.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 {
            st.executeUpdate(query);
        } 
        catch (SQLException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
    }
  });
  return;
}

 . . . .
 . . . .
 . . . .
3
ответ дан GKFX 17 August 2018 в 11:21
поделиться

not Error:

JSONObject json1 = getJsonX(); Ошибка:

JSONObject json2 = null;
if(x == y)
   json2 = getJSONX();

Ошибка: Локальная инструкция переменной, определенная в охватывающей области, должна быть окончательной или эффективной окончательной.

Но вы можете написать:

JSONObject json2 = (x == y) ? json2 = getJSONX() : null;
0
ответ дан mehdi salartayefeh 17 August 2018 в 11:21
поделиться

Я нашел этот подход полезным. Таким образом, вам не нужен класс и окончательный

 btnInsert.addMouseListener(new MouseAdapter() {
        private Statement _statement;

        public MouseAdapter setStatement(Statement _stmnt)
        {
            _statement = _stmnt;
            return this;
        }
        @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();
            }
        }
    }.setStatement(statement));
0
ответ дан user4212919 17 August 2018 в 11:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: