【问题标题】:Atomic Variables Accessed within inner classes在内部类中访问的原子变量
【发布时间】:2021-11-05 22:05:03
【问题描述】:

所以我在这里进行排序并使用内部类实现 Comparator 接口,exceptionMessage 和 didJsonParsingFailed 是在内部类外部声明的变量,现在 java 不允许使用内部类访问局部变量,所以这给了我一个错误,但是当我将这两个变量设为原子变量“AtomicReference”和“AtomicBoolean”时,在这种情况下程序运行良好,我无法理解其背后的原因。使其成为 Atomic 有何帮助? java是否允许访问内部类中的AtomicVariables。

P.S- 我必须在我的 catch 块中修改这些变量,所以我不能让它成为最终的

Collections.sort(list, new Comparator() {
        private static final String KEY_NAME = "createdDateTime";

        @Override public int compare(Object o1, Object o2) {
          String str1;
          String str2;
          Date d1 = new Date();
          Date d2 = new Date();
          try {
            str1 = (String) ((JSONObject) o1).get(KEY_NAME);
            str2 = (String) ((JSONObject) o2).get(KEY_NAME);
            d1 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss").parse(str1);
            d2 = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss").parse(str2);
          } catch (JSONException | ParseException e) {
            exceptionMessage = "xyz";
            didJsonParsingFailed = true;
          }
          return d1.compareTo(d2);
        }

      });

【问题讨论】:

    标签: java sorting inner-classes atomicinteger atomicboolean


    【解决方案1】:

    使其成为 Atomic 有何帮助? java是否允许访问内部类中的AtomicVariables。

    问题是您试图在匿名类中分配变量(即variable = value)。

    你不能这样做,因为匿名类实际上是如何工作的:当你写一个匿名类时,来自外部作用域的变量实际上是匿名类内部的字段,即外部作用域中的变量和匿名类中的变量实际上是不同的;您也不能重新分配,以防止它们不同步。

    另一方面,使用Atomic*,您不是在重新分配变量,而是在重新分配它所拥有的值。这很好,因为匿名类内外的任何变量仍然指向同一个Atomic* 对象;而且,因为它是同一个对象,所以两个地方都可以访问它的值。


    首先,在排序时捕获异常似乎并不是一个特别好的主意。会导致排序不一致、违反总合同等;而不是一个明显有用的排序列表。

    如果您真的坚持,请在sort 调用之外的比较之外捕获异常:

    try {
      Collections.sort(list, new Comparator<JSONObject>() { ... });
    } catch (JSONException | ParseException e) {
      exceptionMessage = "xyz";
      didJsonParsingFailed = true;
    }
    

    假设你真的不需要在 Comparator 内部捕获,它会更容易写成:

    Comparator.comparing(j -> new SimpleDateFormat(/* the date format */).parse(j.get(KEY_NAME)))
    

    【讨论】:

      【解决方案2】:

      我无法理解背后的原因。

      原因是变量exceptionMessagedidJsonParsingFailed 是从内部类中访问的,需要是final 或有效final。

      参考这个answer了解final和有效final!

      使其成为 Atomic 有何帮助?

      简单,当您将其设为原子时,您正在修改原子变量中的内容,而不是更改/分配新的引用!同样适用于 pojo 类,您将变量包装在一个简单的 pojo 类中,如 OuterClassVariables,实例化它并使用它的设置器从内部类或 lambda 主体中设置值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-07-08
        • 2011-08-04
        • 2018-03-04
        • 2015-05-25
        • 1970-01-01
        • 2011-06-15
        • 1970-01-01
        相关资源
        最近更新 更多