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

PhD*_*ira 107 java android

所以标题说明了一切.我的内部出现了编译错误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);

}
Run Code Online (Sandbox Code Playgroud)

Kev*_*hao 123

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

  • 回想起来,如果可以避免使用全局变量是一个坏主意,除非你是初学者,在这种情况下,用globals过度复杂你的程序是很好的学习经验.[这里](http://c2.com/cgi/wiki?GlobalVariablesAreBad)是一篇很好的文章,解释了为什么全局变量是一个坏主意. (12认同)

小智 54

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

方法中定义并由匿名内部类访问的任何变量都必须是final.否则,您可以在内部类中使用该变量,而不会意识到如果变量在内部类中更改,然后稍后在封闭范围中使用它,则内部类中所做的更改不会在封闭范围中保留.基本上,内部类中发生的事情仍然存在于内部类中.

在这里写了一个更深入的解释.它还解释了为什么实例和全局变量不需要声明为final.


Veg*_*ger 43

错误说明了一切,改变:

ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
Run Code Online (Sandbox Code Playgroud)

final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
Run Code Online (Sandbox Code Playgroud)

  • 原因:如果两个方法看到相同的局部变量,Java希望你发誓你不会改变它 - 在Java中说``final`.与缺少引用参数一起,此规则确保仅在其所属的方法中分配局部变量.因此代码更具可读性. (82认同)

the*_*_mr 19

这是一个有趣的答案.

您可以声明最终的单元素数组,并显然更改所需的数组元素.我确定它打破了这个编译器规则首先实现的原因,但是当你像今天一样处于时间绑定时它很方便.

我实际上不能为这一个声称功劳.这是IntelliJ的推荐!感觉有点hacky.但是看起来并不像全局变量那么糟糕,所以我认为值得一提.这只是问题的一个解决方案.不一定是最好的.

final int[] tapCount = {0};

addSiteButton.setOnClickListener(new View.OnClickListener() {

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

});
Run Code Online (Sandbox Code Playgroud)


Sur*_*gch 5

正如@Veger 所说,您可以这样做,final以便可以在内部类中使用该变量。

final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);
Run Code Online (Sandbox Code Playgroud)

我调用它pager而不是mPager因为您将它用作方法中的局部变量onCreate。该m前缀cusomarily保留类的成员变量(即在类的开始声明,并提供给所有的类方法变量)。

如果您确实需要一个类成员变量,那么findViewById将其设为final 是行不通的,因为您不能在onCreate. 解决方案是不使用匿名内部类。这样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);
        }
    };
}
Run Code Online (Sandbox Code Playgroud)