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

匿名 (未验证) 提交于 2019-12-03 02:28:01

问题:

So the title says it all. I'm getting a compilation error inside of my 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);  } 

回答1:

If you don't want to make it final, you can always just make it a global variable.



回答2:

The error says it all, change:

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

to

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


回答3:

You can declare the variable final, or make it an instance (or global) variable. If you declare it final, you won't be able to change it later.

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.



回答4:

As @Veger said, you can make it final so that the variable can be used in the inner class.

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. The m prefix is cusomarily reserved for class member variables (i.e. variables that are declared at the beginning of the class and are available to all class methods).

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. 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.

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);         }     }; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!