java - 从内部类内部访问,需要声明为final

标签 java sql prepared-statement inner-classes

        final int receiverUserId = sendMessageRequest.getReceiverUserId();
        final int senderUserId = sendMessageRequest.getSenderUserId();
        final int replyTo = sendMessageRequest.getReplyTo();
        final int subsiteId = sendMessageRequest.getRelatedSubsiteId();
        final String message = sendMessageRequest.getMessage();


        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplateObject.update(
                new PreparedStatementCreator() {

                    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                        PreparedStatement ps =
                                connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
                        ps.setInt(1, senderUserId);
                        ps.setInt(2, receiverUserId);
                        ps.setInt(3, replyTo);
                        ps.setInt(4, subsiteId);
                        ps.setString(5, message);
                        return ps;
                    }
                },
                keyHolder
        );
        return true;

在上面的代码中,如果我从用于设置 PreparedStatement 的变量之一中删除 final ,它会说 ""从内部类中访问,需要声明为 final

我知道java警告我声明final,所以我不能稍后更改变量并破坏我刚刚创建的实例的PreparedStatementCreater。我在 stackoverflow 上读过类似的主题,但我仍然无法理解。我检查了函数ps.setInt,它的参数是int类型。所以它们是按值传递的。无论如何我都无法改变它们的值(value)。我真的不明白为什么我会在这里收到警告。你能帮我理解一下吗?

最佳答案

这里根本没有传递任何内容(就编译器提示的变量而言)——无论如何,在 Java 中所有内容都是按值传递的,无论是引用值还是原始值。

问题是,您试图在匿名内部类中使用来自外部作用域的局部变量 - 除非该变量是 final ,否则您无法这样做,至少在 Java 7 之前是这样。从 Java 8 开始,您会发现这可行,因为该变量将实际上是final - 您只是无法在外部作用域或内部作用域中更改变量的值。

至于为什么在匿名内部类的主体中使用的局部变量必须是最终的 - 据我所知,这是为了避免混淆 - 并且可能有助于简化实现。完全可能设计一种语言,其中闭包中的变量可以是可变的(例如,C# 就是这样),但是 Java 的模型创建匿名内部类的实例,其中包含匿名内部类主体中使用的所有变量的副本。这很容易理解(您无法观察到任何更改,因为您不允许进行任何更改),这意味着您最终不会生成额外的类来保存外部作用域中使用的变量。

关于java - 从内部类内部访问,需要声明为final,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27216232/

相关文章:

php - Postgres/PHP PDO::PDOStatement->bindParam() 到 character(1) 字段

java - 尽管存在唯一约束,MySQL 数据库仍有重复条目

php - UPDATE Multiple ID 中的 PDO 准备语句

java - JAXWS-RI WSGEN 配置为使用特定的 JDK

java - 在单独的行上打印一行的每个元素?

java - Oreo 中我自己的 URI 上的 ContentProvider.notifyChange 的安全异常

java - 如何在 JOGL 中移动相机眼睛位置?

mysql - 比较字符串与大量记录的相似度

c# - 有人可以解释为什么这两个 linq 查询返回不同的结果吗?

java - 如何使用 2 列合并的字段执行查询?