【问题标题】:is accessed from within inner class, needs to be declared final从内部类中访问,需要声明为final
【发布时间】:2014-12-01 01:55:43
【问题描述】:
        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,它会显示"" is accessed from within inner class, needs to be declared final

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

【问题讨论】:

  • PreparedStatement无关。您在匿名类中使用该变量,这就是为什么它必须是最终的。阅读this answer了解更多信息。

标签: java sql prepared-statement inner-classes


【解决方案1】:

这里根本没有传递(就编译器抱怨的变量而言) - 无论如何,在 Java 中一切都是按值传递的,无论是引用还是原始值。 p>

问题是您试图在匿名内部类中使用外部范围内的局部变量 - 除非变量是 final,否则您不能这样做,至少在 Java 7 中包括在内. 从 Java 8 开始,您会发现这会起作用,因为变量 实际上是最终的 - 您无法在外部范围或内部范围内更改变量的值范围。

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

【讨论】:

  • 所以基本上是阻止我认为我可以在外部范围内更改内部类变量的值吗?
  • @Ozum:或者反过来。
猜你喜欢
  • 2019-09-22
  • 2018-07-13
  • 2016-03-18
  • 1970-01-01
  • 2015-07-24
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多