【问题标题】:Cant solve "local variable needs to be final"无法解决“局部变量需要是最终的”
【发布时间】:2018-10-02 23:41:36
【问题描述】:

您好,我正在尝试根据用户请求从我的数据库中添加计算,但我的浮点数将无法工作,除非它是最终的,我该如何解决这个问题?

代码:

float v = (float) 0;
    StringBuilder upcoming = new StringBuilder("Upcoming\n\n");
    StringBuilder Results = new StringBuilder("Upcoming\n\n");
    switchExam.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if(!isChecked)
            {
                for(FAssessment a : assessmentList) {
                    if(!a.getType().equals("Final"))
                    {
                        double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                        v += (float) d;
                    }                        
                }
            }
            else
            {
                for(FAssessment a : assessmentList) {
                    double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                    v += (float) d;
                }
            }
        }
    });

这是我得到错误v += (float) d;的地方

从内部类中访问变量“v”,需要是最终的或有效的最终

【问题讨论】:

  • 您正在创建一个匿名类用作OnCheckedChangeListener。该事件在将来会发生在switchExam 对象上,在当前函数完成之后(我的意思是float v 的作用域是函数),那么新值将存储在哪里?由于该变量将不再可用,因此存储对它的引用是没有意义的。见stackoverflow.com/questions/4732544/…

标签: java android variables


【解决方案1】:

据我了解,您想稍后再次使用此变量v。如果是这样,您可以获取所需的代码并将其放入方法中。这样您就可以在listener 中声明变量,这将给它它正在寻找的final

像这样:

switchExam.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            StringBuilder upcoming = new StringBuilder("Upcoming\n\n");
            StringBuilder Results = new StringBuilder("Results\n\n");
            float v= 0;
            if(!isChecked)
            {

                for(FAssessment a : assessmentList) {
                    if(!a.getType().equals("Final"))
                    {
                        double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                        v += (float) d;
                    }

                    upcoming.append(a.getDesc()+" "+a.getDate()+"\n");
                    Results.append(a.getDesc()+" "+format.format(((a.getAchieved()/a.getTotal())*100))+"%\n");
                }                    
                SetInit(v,upcoming,Results);
            }
            else
            {
                for(FAssessment a : assessmentList) {
                    double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                    v += (float) d;
                    upcoming.append(a.getDesc()+" "+a.getDate()+"\n");
                    Results.append(a.getDesc()+" "+format.format(((a.getAchieved()/a.getTotal())*100))+"%\n");
                }
                SetInit(v,upcoming,Results);

            }
        }
    });
    switchExam.setChecked(true);

然后在您的方法中,您将粘贴您想要对变量 v 执行的操作:

private void SetInit(float v, StringBuilder coming, StringBuilder results) {
    txtUpcoming.setText(coming);
    txtResults.setText(results);
    //And whatever you want to do with `v`
 }

希望这会有所帮助。 :)

【讨论】:

  • 非常感谢,这有帮助!
【解决方案2】:

也许反过来谁保留什么?

StringBuilder upcoming = new StringBuilder("Upcoming\n\n");
StringBuilder Results = new StringBuilder("Upcoming\n\n");

CompoundButton.OnCheckedChangeListener lister = new CompoundButton.OnCheckedChangeListener() {

    float v = 0.0;
    public float getV() { return v; }

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if(!isChecked)
        {
            for(FAssessment a : assessmentList) {
                if(!a.getType().equals("Final"))
                {
                    double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                    v += (float) d;
                }                        
            }
        }
        else
        {
            for(FAssessment a : assessmentList) {
                double d = CalculatePercentage(a.getTotal(),a.getAchieved(),Double.parseDouble(a.getWeight()));
                v += (float) d;
            }
        }
    }
};
switchExam.setOnCheckedChangeListener(lister);

那么当封闭程序需要知道 v 是什么时它可以调用

lister.getV();

注意:除了将 0 转换为浮点数,您还可以这样说:

float v = 0f;

【讨论】:

  • Another 换一种说法:“原因:如果两个方法看到同一个局部变量,Java 想让你发誓你不会改变它——最终,用 Java 说话。加上没有通过引用参数,此规则确保本地仅在它们所属的方法中分配..."
  • 非常感谢您的意见,我试过了,但没有成功
猜你喜欢
  • 2014-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-05
  • 2017-11-07
  • 2017-11-01
  • 1970-01-01
  • 2017-10-22
相关资源
最近更新 更多