Подтвердить что ты не робот

Как передать переменную в новую декларацию Runnable?

У меня есть следующее:

Runnable done = new Runnable()
    {
        public void run()
        {
            System.out.println("Hello");
        }
    };

И затем в моей активности Android я буду называть что-то вроде:

runOnUIThread(done);

Что я тогда называю. Однако я хочу, чтобы "Hello" не был жестко закодирован, поэтому я могу передать его. В противном случае мне нужно будет иметь одно из этих объявлений для каждой строки, которую я хочу распечатать.

(Это вопрос андроида, но он сместил его на базовую Java, чтобы было легче ответить)

Спасибо

4b9b3361

Ответ 1

final String hello = whereverItsComingFrom;
Runnable done = new Runnable()
    {
        public void run()
        {
            System.out.println(hello);
        }
    };

Ответ 2

В Java (и я считаю, что это то же самое и в Android), вы можете использовать анонимный внутренний класс, как это предложил Барт Ван Хекелом. Это решение имеет то преимущество, что приходится писать меньше кода, и вы можете получить доступ к полям и методам внешнего класса.

Но у него есть 2 недостатка:

  • переменная "привет" должна быть окончательной,

  • анонимный класс имеет внутреннюю ссылку на экземпляр внешнего класса - это означает, что внешний класс сохраняется, если в противном случае он будет иметь право на сбор мусора. @See: Эффективная Java [Joshua Bloch], Пункт 22: Использовать статические классы-члены над нестатическими

И по моему скромному мнению, это плохая практика параметризировать экземпляр класса таким образом.

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

class Demo {
...

  private static class MyRunnable implements Runnable {
     private final String message;

     MyRunnable(final String message) {
       this.message = message;
     }

     public void run() {
       System.out.println(message);
     }
  }

  public void startThread() {
    MyRunnable myRunnable = new MyRunnable("Hello");

    runOnUIThread(myRunnable); 
  }
...
}