[java] 변수는 내부 클래스 내에서 액세스됩니다. 최종 선언 필요

그래서 제목은 모든 것을 말합니다. 내 .NET 내부에서 컴파일 오류가 발생 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);

}



답변

최종적으로 만들고 싶지 않다면 항상 전역 변수로 만들 수 있습니다.


답변

변수를 final로 선언하거나 인스턴스 (또는 전역) 변수로 만들 수 있습니다. 최종적으로 선언하면 나중에 변경할 수 없습니다.

메서드에 정의되고 익명 내부 클래스에서 액세스하는 모든 변수는 최종 변수 여야합니다. 그렇지 않으면 내부 클래스에서 해당 변수를 사용할 수 있습니다. 변수가 내부 클래스에서 변경된 다음 나중에 엔 클로징 범위에서 사용되는 경우 내부 클래스에서 변경된 내용이 엔 클로징 범위에서 유지되지 않는다는 사실을 알지 못합니다. 기본적으로 내부 클래스에서 일어나는 일은 내부 클래스에 남아 있습니다.

여기에 더 자세한 설명을 썼습니다 . 또한 인스턴스 및 전역 변수를 final로 선언 할 필요가없는 이유도 설명합니다.


답변

오류는 모든 것을 말합니다.

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

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


답변

재미있는 대답이 있습니다.

최종 단일 요소 배열을 선언하고 배열의 요소를 원하는대로 변경할 수 있습니다. 이 컴파일러 규칙이 처음에 구현 된 바로 그 이유를 깨뜨릴 것이라고 확신하지만, 오늘처럼 타임 바인드에있을 때 편리합니다.

나는 실제로 이것에 대한 크레딧을 청구 할 수 없습니다. IntelliJ의 추천이었습니다! 약간 엉뚱한 느낌입니다. 그러나 전역 변수만큼 나쁘지는 않아서 여기서 언급 할 가치가 있다고 생각했습니다. 문제에 대한 하나의 해결책 일뿐입니다. 반드시 최고의 것은 아닙니다.

final int[] tapCount = {0};

addSiteButton.setOnClickListener(new View.OnClickListener() {

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

});


답변

@Veger가 말했듯 final이 변수를 내부 클래스에서 사용할 수 있도록 만들 수 있습니다.

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

나는 그것을라는 pager것이 아니라 mPager당신이에서 로컬 변수로 사용하고 있기 때문에 onCreate방법. m접두사는 cusomarily 클래스 멤버 변수 (클래스의 시작 부분에 선언 된 모든 클래스 메소드에 사용할 수 있습니다 즉, 변수를) 예약되어 있습니다.

당신이 실제로 클래스 멤버 변수를해야하는 경우, 그것은 최종 사용자가 사용할 수 없기 때문에 할 작동하지 않습니다 findViewById때까지 값을 설정합니다 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);
        }
    };
}


답변

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


답변