новый объект {} Construct - PullRequest
       3

новый объект {} Construct

23 голосов
/ 11 сентября 2010

В Java стандартным способом создания объекта является использование

MyClass name = new MyClass();

. Я также часто вижу конструкцию

new MyClass() { /*stuff goes in here*/ };

Я давно искал онлайн и могуНе можете найти хорошее объяснение того, что делает второй стиль конструкции или как он это делает.

Может кто-нибудь объяснить, как и почему вы бы использовали вторую конструкцию?

Ответы [ 6 ]

22 голосов
/ 11 сентября 2010

Эта конструкция фактически делает две вещи: 1) она объявляет анонимный класс, который расширяет класс, который вы используете в конструкторе, и 2) создает экземпляр этого анонимного класса.

Редактировать: при использовании такой конструкции вы можете наблюдать анонимный класс, просматривая сгенерированные файлы .class.Существует обычный MyClass.class файл и еще один для каждого анонимного подкласса: MyClass$1.class для первого и т. Д.

12 голосов
/ 11 сентября 2010

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

Существует также трюк под названием инициализация двойной скобкой , где вы можете обойтись без синтаксиса для буквенных карт и списков, используя анонимные классы, например:

Map map = new HashMap() {{put("foo", 1); put("bar", 2);}};

Здесь вложенные фигурные скобки создают инициализатор экземпляра. Объект, связанный с map, не является HashMap, его класс является анонимным классом, расширяющим HashMap. (Это означает, что если у вас есть правило PMD о классах, которым нужно объявлять серийные идентификаторы, тогда оно будет жаловаться на это.)

7 голосов
/ 11 сентября 2010

Как уже говорили другие, он создает экземпляр анонимного класса с подклассом Class.Вот пример того, как он обычно используется:

panel.addMouseListener(
  new MouseAdapter () {
    @Override
    public void mouseEntered(MouseEvent e) {
      System.out.println(e.toString());
    }
  }
);

Приведенный выше код создает экземпляр анонимного класса, который расширяет MouseAdapter.В анонимном классе метод mouseEntered был переопределен, чтобы продемонстрировать, что анонимный класс работает в основном как любой другой класс.Это очень удобный и распространенный способ создания (обычно простых) слушателей.

3 голосов
/ 11 сентября 2010

Вторая конструкция создает экземпляр анонимного класса, который является подклассом Class.

0 голосов
/ 05 мая 2019

Начиная с jdk8 вы, возможно, видели другой синтаксис, напоминающий создание объектов при использовании лямбда-выражений.

ПРИМЕЧАНИЕ: Лямбда-выражения не переводятся в анонимные внутренние классы, они используют вызов динамического , который был представлен в Java 7 для выполнения функциональных методов.

Например:

public class LambdaSample {

    public static void main(String[] args) {
        //If implementation is only one statement then {} braces are optional
        Runnable oneLineImplRunnable = ()->System.out.println("This is one line lambda expression");
        //Multiple statements in the implementation then {} braces are mandatory
        Comparator<StudentTest> stdComparator = (StudentTest s1,StudentTest s2)->{
            if(s1.getFirstName().equals(s2.getFirstName())) {
                return s1.getLastName().compareTo(s2.getLastName());
            }else {
                return s1.getFirstName().compareTo(s2.getFirstName());
            }
        };
    }
}
0 голосов
/ 04 мая 2019

Если вы хотите создать объект с помощью конструктора защиты из другого пакета, вы можете использовать:

new Foo() {};

, иначе вы получите ошибку доступа.Он равен анонимному подклассу, унаследованному от класса Foo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...