变量在内部类中被访问。需要声明为 final

我的 onClick内部出现编译错误。

这是密码。

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


}
233808 次浏览

错误说明了一切,改变:

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

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

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

您可以声明变量 final,或者使其成为一个实例(或全局)变量。如果您声明它是最终的,那么以后您将无法更改它。

在方法中定义并由匿名内部类访问的任何变量都必须是 final 的。否则,您可以在内部类中使用该变量,不知道如果该变量在内部类中发生更改,然后在后面的封闭作用域中使用,则在内部类中所做的更改不会在封闭作用域中持久存在。基本上,在内部类中发生的事情保留在内部类中。

我写了一个更多的 详细解释。它也解释了为什么实例和全局变量不需要声明为 final。

正如@Veger 所说,您可以将其设置为 final,这样变量就可以在内部类中使用。

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

我将其称为 pager而不是 mPager,因为您在 onCreate方法中将其用作局部变量。m前缀通常保留给类成员变量(即在类的开头声明并可用于所有类方法的变量)。

如果您确实需要一个类成员变量,那么它不能使它成为 final,因为在 onCreate之前不能使用 findViewById来设置它的值。解决方案是不使用匿名内部类。这样,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);
}
};
}

有个有趣的回答。

您可以声明一个最终的单元素数组,并且显然可以随心所欲地更改数组的元素。我敢肯定它打破了这个编译器规则最初实现的原因,但是当你像我今天一样处于时间限制时,它很方便。

事实上我不能把这个归功于自己。这是 IntelliJ 的建议!感觉有点古怪。但似乎没有全局变量那么糟糕,所以我认为这里值得一提。这只是解决问题的一个办法。不一定是最好的。

final int[] tapCount = {0};


addSiteButton.setOnClickListener(new View.OnClickListener() {


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


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