代码之家  ›  专栏  ›  技术社区  ›  user7913931

为什么我需要在@Override[内部类]方法内将变量转换为最终数组?

  •  3
  • user7913931  · 技术社区  · 8 年前

     public void addConditions(){
        final String arriveHourse, departHourse, arriveMinutes, departMinutes;
        TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
    
                departHourse = String.valueOf(selectedHours);
                departMinutes = String.valueOf(selectedMinutes);
    
            }
        };
    
    ...
    }
    

    为什么IDE要求我转换 departHourse

    为什么会发生这种情况,我该如何避免?

    此外,如果我将变量移到类外,其工作方式如下:

    String arriveHourse, departHourse, arriveMinutes, departMinutes;
    
    public void addConditions(){
    
        TimePickerDialog.OnTimeSetListener departOnTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker timePicker, int selectedHours, int selectedMinutes) {
    
                departHourse = String.valueOf(selectedHours);
                departMinutes = String.valueOf(selectedMinutes);
    
            }
        };
    
    ...
    }
    
    2 回复  |  直到 8 年前
        1
  •  4
  •   Jon Skeet    8 年前

    departHourse 是最终变量。它必须是,才能在匿名内部类中使用。这意味着您不能在匿名内部类中为其分配新值。

    final String[] valueHolder = new String[1];
    ...
    Foo foo = new Foo() {
        @Override public void bar() {
            valueHolder[0] = "Set in bar";
        }
    }
    

    另一种选择是使用 AtomicReference :

    final AtomicReference<String> valueHolder = new AtomicReference<String>();
    ...
    Foo foo = new Foo() {
        @Override public void bar() {
            valueHolder.set("Set in bar");
        }
    }
    

    在这两种情况下,您都可以在不更改 valueHolder 变量本身。

        2
  •  0
  •   Yahor Paulavets    8 年前

    http://wiki.c2.com/?ClosuresThatWorkAroundFinalLimitation

    最好的答案是: Lambdas: local variables need final, instance variables don't

    @override 这不是您需要声明参数final的原因,原因是-它们在闭包中用作参数/局部变量!