Вы можете рассмотреть стороннюю службу электронной почты, которая обрабатывает проблемы с доставкой:
Вы можете объявить переменную final или сделать ее переменной экземпляра (или глобальной). Если вы объявите его окончательным, вы не сможете изменить его позже.
Любая переменная, определенная в методе и доступная анонимным внутренним классом, должна быть окончательной. В противном случае вы можете использовать эту переменную во внутреннем классе, не сознавая, что если переменная изменяется во внутреннем классе, а затем она используется позже в охватывающей области, изменения, сделанные во внутреннем классе, не сохраняются в охватывающей области. В основном, то, что происходит во внутреннем классе, остается во внутреннем классе.
Я написал более подробное объяснение здесь . Он также объясняет, почему экземпляры и глобальные переменные не обязательно должны быть объявлены окончательными.
Если вы не хотите делать это окончательным, вы всегда можете просто сделать глобальную переменную.
Как сказал @Veger, вы можете сделать его final
, чтобы переменная могла использоваться во внутреннем классе.
final ViewPager pager = (ViewPager) findViewById(R.id.fieldspager);
Я назвал его pager
, а не mPager
, потому что вы используют его как локальную переменную в методе onCreate
. Префикс m
зарезервирован для переменных класса (т.е. переменных, объявленных в начале класса и доступных для всех методов класса).
Если вам действительно нужна переменная-член класса, он не работает, чтобы сделать его окончательным, потому что вы не можете использовать findViewById
, чтобы установить его значение до onCreate
. Решение состоит в том, чтобы не использовать анонимный внутренний класс. Таким образом, переменная mPager
не обязательно должна быть объявлена окончательной и может использоваться во всем классе.
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]++;
}
});
Ошибка говорит об этом, измените:
ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
на
final ViewPager mPager = (ViewPager) findViewById(R.id.fieldspager);
final
, в Java говорят. Вместе с отсутствием параметров ссылки, это правило гарантирует, что locals назначаются только в том методе, к которому они принадлежат. Таким образом, код более читабельен.
– ignis
20 January 2013 в 17:21
addSiteButton.setOnClickListener(new View.OnClickListener() {
, есть ли у вас какие-либо идеи, почему это произойдет?
– PhDeOliveira
21 January 2013 в 18:52
null
. Вероятно, findViewById возвращает null
. Я не могу сказать больше, не будучи программистом на Android; Я советую вам открыть отдельный вопрос. Конечно, это не имеет ничего общего с внутренними классами, final, et similia i>.
– ignis
21 January 2013 в 23:02