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

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

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

MyClass name = new MyClass();

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

new Foo() {};

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

Ответ 6

Начиная с 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());
            }
        };
    }
}