Новый объект {} Construct
В Java стандартный способ создания объекта использует
MyClass name = new MyClass();
Я также часто вижу конструкцию
new MyClass() { /*stuff goes in here*/ };
Я искал онлайн какое-то время и не могу найти хорошее объяснение того, что делает второй стиль конструкции и как он это делает.
Может кто-нибудь объяснить, как и почему вы будете использовать вторую конструкцию?
Ответы
Ответ 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());
}
};
}
}