2012-07-03 3 views
8

Мне нужно было изменить переменные внутри внутреннего класса, и я получил позорную ошибку «Не могу ссылаться на неконфигурированную переменную внутри внутреннего класса, определенного другим методом».внутренний класс не конечная переменная java

void onStart(){ 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     int q = i; 
    } 
    }); 
} 

Я быстро сделал класс, который провел все вещи, которые я хотел изменить и сделал окончательный вариант класса за пределами внутреннего класса

class temp{ 
    int q; 
} 

void onStart(){ 
    final temp x = new temp(); 
    bt.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     x.q = i; 
    } 
    }); 
} 

Это, кажется, что мне нужно, и это работает, но мне интересно, правильно ли это решить проблему. Кроме того, я действительно ненавижу использовать слово temp, чтобы назвать мой класс. Есть ли реальный термин программирования для того, что я сделал, чтобы сделать более описательное имя для моего класса?

ответ

9

Вы можете просто создать внутренний класс вместо анонимного (как вы сейчас делаете). Затем у вас есть конструктор и любые другие методы, которые вы хотите установить для своих участников. Не требуется хакерство (например, массив из 1 случая).

Я считаю это более чистым, если класс требует какого-либо обмена данными со своим внешним классом, но признайте, что это личное предпочтение. Массив из 1 идиомы будет работать также и является более кратким, но, откровенно говоря, он просто выглядит уродливо. Обычно я ограничиваю анонимные внутренние классы теми, кто просто выполняет действия, не пытаясь обновлять данные во внешнем классе.

Например:

private MyListener listener = new MyListener(); 

void onStart(){ 
    bt.setOnClickListener(listener); 
} 

class MyListener implements OnClickListener 
{ 
    String name; 
    int value; 

    void setName(String newName) 
    { 
     name = newName; 
    } 

    void setValue(int newValue) 
    { 
     value = newValue; 
    } 

    public void onClick(View v) 
    { 
     // Use the data for some unknown purpose 
    } 
} 

Если есть несколько потоков, участвующих, то соответствующие синхронизации должны быть использованы также.

+0

Bravo. Другая приятная вещь заключается в том, что этот внутренний класс более расширяемый и многоразовый. ИМО, анонимные внутренние классы - почти всегда плохая идея. – user949300

+0

Они хорошо работают как один из классов стиля действия, обработчики для определенных событий, в которых действия могут выполняться на основе входных данных. Очень часто в GUI-программировании, что является его примером. За исключением этого случая существует такое взаимодействие между классами, которое усложняет вопросы. – Robin

+0

Это то, что я искал! Благодаря! –

2

Я опубликовал аналогичный ответ в своем other thread here. В основном идея состоит в создании «обертки», которая обертывает почти любой тип Object. Поскольку final в Java означает «без переназначения», а не «постоянный», этот трюк в значительной степени подходит. Но, как упоминалось в первоначальном посте, убедитесь, что вы осторожно выполняете его при использовании в многопоточной среде.

0

Я бы сохранил ссылку на ваш прослушиватель кликов во внешнем классе и сделал int переменной-членом в вашем слушателе. Просто сохраните переменную в прослушивателе при щелчке, а затем возьмите переменную во внешнем классе, когда вам это нужно, вместо того, чтобы устанавливать ее в точке щелчка.

Проще говоря, если внутренний класс должен изменить его, сделайте его переменной во внутреннем классе.

0

Поскольку вы, кажется, устанавливаете несколько вещей (из комментариев), создайте метод в основном классе, button1WasClicked() (лучше имя может быть выполненоUpdate, doSave и т. Д. - что-то, что имеет отношение к тому, что делает кнопка), положить соответствующий код там, и вызовите его из внутреннего класса/слушателя. (Если вы используете Swing, я сделал бы это действие, YMMV)

Таким образом, если позже есть меню или намерение или жест, которым необходимо выполнить один и тот же материал, вызов есть.

Смежные вопросы