Использование определений классов внутри метода в Java

Пример:

public class TestClass
{
    public static void main(String[] args) 
    {
        TestClass t = new TestClass();
    }

    private static void testMethod(){
        abstract class TestMethod{
            int a;
            int b;
            int c;

            abstract void implementMe();
        }

        class DummyClass extends TestMethod{
            void implementMe(){

            }
        }

        DummyClass dummy = new DummyClass();
    }
}

Я узнал, что вышеупомянутый фрагмент кода совершенно легален в Java. У меня есть следующие вопросы.

  • Какое использование когда-либо имеет определение класса внутри метода?
  • Будет создан файл класса для DummyClass
  • Мне трудно представить эту концепцию в объектно-ориентированной манере. Наличие определения класса внутри поведения. Вероятно, кто-то может сказать мне с примерами реальных реальностей.
  • Абстрактные классы внутри метода звучат немного сумасшедшим для меня. Но никаких интерфейсов не разрешено. Есть ли причина в этом?

Ответ 1

Это называется локальным классом.

2 является простым: да, будет создан файл класса.

1 и 3 - один и тот же вопрос. Вы бы использовали локальный класс, где вам никогда не нужно было создавать экземпляр одного или знать подробности реализации в любом месте, но одним способом.

Типичным применением было бы создание отбрасываемой реализации некоторого интерфейса. Например, вы часто увидите что-то вроде этого:

  //within some method
  taskExecutor.execute( new Runnable() {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }); 

Если вам нужно создать кучу и сделать что-то с ними, вы можете изменить это на

  //within some method
  class myFirstRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomething( parameter );
       }
  }
  class mySecondRunnableClass implements Runnable {
       public void run() {
            classWithMethodToFire.doSomethingElse( parameter );
       }
  }
  taskExecutor.execute(new myFirstRunnableClass());
  taskExecutor.execute(new mySecondRunnableClass());

Что касается интерфейсов: я не уверен, есть ли техническая проблема, которая делает локально определенные интерфейсы проблемой для компилятора, но даже если их нет, они не добавят никакого значения. Если локальный класс, реализующий локальный интерфейс, использовался вне метода, интерфейс был бы бессмыслен. И если локальный класс будет использоваться только внутри метода, как интерфейс, так и класс будут реализованы внутри этого метода, поэтому определение интерфейса будет избыточным.

Ответ 2

Они называются локальными классами. Вы можете найти подробное объяснение и пример здесь. В примере возвращается конкретная реализация, о которой нам не нужно знать вне метода.

Ответ 3

  • Класс не может быть замечен (т.е. экземпляр, его методы доступны без Reflection) вне метода. Кроме того, он может обращаться к локальным переменным, определенным в testMethod(), но до определения класса.

  • Я действительно подумал: "Никакого такого файла не будет написано". пока я просто не попробовал: да, такой файл создан! Он будет называться чем-то вроде A $1B.class, где A - внешний класс, а B - локальный класс.

  • Специально для функций обратного вызова (обработчики событий в графических интерфейсах, например onClick(), когда нажата кнопка и т.д.), довольно привычно использовать "анонимные классы" - прежде всего потому, что вы можете получить много из них. Но иногда анонимные классы недостаточно хороши - особенно, вы не можете определить конструктор на них. В этих случаях эти локальные классы методов могут быть хорошей альтернативой.

Ответ 4

Настоящая цель состоит в том, чтобы позволить нам создавать классы, встроенные в вызовы функций, для консолей тех из нас, кто любит делать вид, что мы пишем на функциональном языке;)

Ответ 5

Единственный случай, когда вы хотите иметь полнофункциональный внутренний класс класса против анонимного класса (закрытие Java. a.k.a.) - это когда выполняются следующие условия:

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

например. кто-то хочет Runnable, и вы хотите записать, когда выполнение началось и закончилось.

С анонимным классом это невозможно, с внутренним классом вы можете это сделать.

Вот пример, демонстрирующий мою точку

private static void testMethod (
        final Object param1,
        final Object param2
    )
{
    class RunnableWithStartAndEnd extends Runnable{
        Date start;
        Date end;

        public void run () {
            start = new Date( );
            try
            {
                evalParam1( param1 );
                evalParam2( param2 );
                ...
            }
            finally
            {
                end = new Date( );
            }
        }
    }

    final RunnableWithStartAndEnd runnable = new RunnableWithStartAndEnd( );

    final Thread thread = new Thread( runnable );
    thread.start( );
    thread.join( );

    System.out.println( runnable.start );
    System.out.println( runnable.end );
}

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

Ответ 6

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

Наличие внутренних классов помогает в обеспечении того, чтобы этот класс не был доступен для внешнего мира. Это справедливо, особенно для случаев программирования пользовательского интерфейса в GWT или GXT и т.д., Где код генерации JS написан в java, и поведение для каждой кнопки или события должно определяться путем создания анонимных классов

Ответ 7

создать объект в классе

object ob=new object();

метод in

void method( object ob)
ob= this.ob;

объект добавляется, который создается в классе