简体   繁体   English

在内部类中访问变量。 需要宣布为最终

[英]Variable is accessed within inner class. Needs to be declared final

I'm getting a compilation error inside of my onClick .我的onClick出现编译错误。

Here's the code.这是代码。

public class fieldsActivity extends Activity {

Button addSiteButton;
Button cancelButton;
Button signInButton;


/**
 * Called when the activity is first created.
 */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // to create a custom title bar for activity window
    requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

    setContentView(R.layout.fields);
    // use custom layout title bar
    getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.topbar);

    Pager adapter = new Pager();
    ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
    mPager.setAdapter(adapter);
    mPager.setCurrentItem(1);



    addSiteButton = (Button) findViewById(R.id.addSiteButton);
    addSiteButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
           mPager.setCurrentItem(2, true); //Compilation error happens here.
        }


    });


    cancelButton = (Button) findViewById(R.id.cancel_button);
    signInButton = (Button) findViewById(R.id.sign_in_button);

}

如果你不想让它成为最终的,你总是可以让它成为一个全局变量。

You can declare the variable final, or make it an instance (or global) variable.您可以将变量声明为 final,或使其成为实例(或全局)变量。 If you declare it final, you won't be able to change it later.如果您将其声明为 final,则以后将无法更改它。

Any variable defined in a method and accessed by an anonymous inner class must be final.任何在方法中定义并由匿名内部类访问的变量都必须是最终的。 Otherwise, you could use that variable in the inner class, unaware that if the variable changes in the inner class, and then it is used later in the enclosing scope, the changes made in the inner class did not persist in the enclosing scope.否则,您可以在内部类中使用该变量,不知道如果该变量在内部类中更改,然后在封闭范围内使用,则内部类中所做的更改不会在封闭范围内持续存在。 Basically, what happens in the inner class stays in the inner class.基本上,内部类中发生的事情会留在内部类中。

I wrote a more in-depth explanation here .在这里写了一个更深入的解释 It also explains why instance and global variables do not need to be declared final.它还解释了为什么不需要将实例变量和全局变量声明为 final。

The error says it all, change:错误说明了一切,更改:

ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

to

final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);

Here's a funny answer.这是一个有趣的答案。

You can declare a final one-element array and change the elements of the array all you want apparently.您可以声明一个最终的单元素数组,并显然可以随意更改数组的元素。 I'm sure it breaks the very reason why this compiler rule was implemented in the first place but it's handy when you're in a time-bind as I was today.我敢肯定它打破了最初实现此编译器规则的真正原因,但是当您像我今天一样处于时间限制中时,它很方便。

I actually can't claim credit for this one.我实际上不能为这个申请功劳。 It was IntelliJ's recommendation!这是 IntelliJ 的推荐! Feels a bit hacky.感觉有点鸡肋。 But doesn't seem as bad as a global variable so I thought it worth mentioning here.但似乎不像全局变量那么糟糕,所以我认为这里值得一提。 It's just one solution to the problem.这只是解决问题的一种方法。 Not necessarily the best one.不一定是最好的。

final int[] tapCount = {0};

addSiteButton.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
       tapCount[0]++;
    }

});

As @Veger said, you can make it final so that the variable can be used in the inner class.正如@Veger 所说,您可以将其设为final以便可以在内部类中使用该变量。

final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);

I called it pager rather than mPager because you are using it as a local variable in the onCreate method.我称它为pager而不是mPager因为您将它用作onCreate方法中的局部变量。 The m prefix is cusomarily reserved for class member variables (ie variables that are declared at the beginning of the class and are available to all class methods). m前缀通常是为类成员变量保留的(即在类的开头声明的变量,可用于所有类方法)。

If you actually do need a class member variable, it doesn't work to make it final because you can't use findViewById to set its value until onCreate .如果您确实需要一个类成员变量,则无法将其设为 final,因为在onCreate之前您无法使用findViewById设置其值。 The solution is to not use an anonymous inner class.解决方案是不使用匿名内部类。 This way the mPager variable doesn't need to be declared final and can be used throughout the class.这样mPager变量不需要声明为 final 并且可以在整个类中使用。

public class MainActivity extends AppCompatActivity {

    private ViewPager mPager;
    private Button mButton;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // ...

        mPager = (ViewPager) findViewById(R.id.fieldspager);

        // ...

        mButton.setOnClickListener(myButtonClickHandler);
    }


    View.OnClickListener myButtonClickHandler = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mPager.setCurrentItem(2, true);
        }
    };
}
    public class ConfigureActivity extends Activity {

        EditText etOne;
        EditText etTwo;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_configure);

            Button btnConfigure = findViewById(R.id.btnConfigure1);   
            btnConfigure.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            configure();
                        }
                    });
    }

    public  void configure(){
            String one = etOne.getText().toString();
            String two = etTwo.getText().toString();
    }
}

When you create an inner class About actually a compiler generate a new class - <ClassName>$<Counter>.class , and pass next parameters into constructor Local variable on stack 当您创建一个inner class 关于编译器时,实际上会生成一个新类- <ClassName>$<Counter>.class ,然后将下一个参数传递给构造函数中的本地变量

  1. reference to outer class 参考外层阶级
  2. final local variables that are used inside 内部使用的最终局部变量

There is no possibility to reassign the variable from a constructor (or method) but it is simple to change the state of passed variable. 无法从构造函数(或方法) 重新分配变量,但更改传递变量的状态很简单。 That is why you can use: 这就是为什么您可以使用:

  1. a field of outer class 外在领域
  2. final local variable which is reference type (eg Object ...) and change it's state inside the inner class 最终的局部变量,它是引用类型(例如Object ...),并在内部类中更改其状态
  3. wrap a local variable that is value type (eg int ...) and pass it as a reference type ( IntelliJ IDEA propose you to transform a variable into final one element array) 包装一个值为值类型(例如int ...)的局部变量,并将其作为引用类型传递( IntelliJ IDEA建议您将变量转换为最终的一个元素数组)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在内部类中访问变量“名称”。 需要宣布为最终 - Variable “name” is accessed within inner class. Needs to be declared final 在内部类中访问变量。 需要声明为final。但我不想声明为final - Variable is accessed within inner class. Needs to be declared final.But I don't want to declared Final 在内部 class 中访问变量。 将对话框添加到列表视图时需要声明为 final - Variable is accessed within inner class. Needs to be declared final when adding a dialog to a list view 从内部类访问变量“ ”,需要声明为 final - Variable ' ' is accessed from within inner class, needs to be declared final 从内部 class 访问的变量需要声明为 final - Variable accessed from within inner class needs to be declared final “从内部类访问变量需要声明为final”错误 - "variable is accessed from within inner class needs to be declared final" error 变量(dialogView)是从内部类中访问的,需要声明为final - Variable (dialogView) is accessed from within inner class, needs to be declared final 需要在OnTouchListener中用MediaPlayer声明内部类中访问的变量的最终声明 - Variable Is Accessed Within Inner Class Needs to be Declared Final with MediaPlayer In a OnTouchListener 在内部类中访问如何解析变量,并且需要将其声明为final - How to resolve variable is accessed within inner class and needs to be declared final 从内部类访问变量“i”,需要声明为 final - Variable 'i' is accessed from within inner class, needs to be declared final
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM