Что касается анонимных классов, в документации Oracle говорится, что ...
They are like local classes except that they do not have a name. Use them if you need to use a local class only once
Теперь, учитывая, что локальные классы (насколько мне известно) являются классами, определенными в методе (или какой-либо другой локальной конструкции), например, следующим ... (где MyInterface - это интерфейс с абстрактным методом тестирования)
public void localTest(){
MyInterface mi = new MyInterface(){
@Override
public void test(){System.out.println("test");};
};
}
Вышесказанное в порядке и подпадает под определение, приведенное выше, однако я также могу определить следующее ...
class MyClass{
MyInterface mi = new MyInterface(){
@Override
public void test(){System.out.println("test");};
};
}
Это не входит в метод, поэтому не является классом «Локальный» и поэтому не подпадает под приведенное выше определение. Могу ли я где-нибудь прочитать об этих типах анонимных классов (анонимных классов-членов, если хотите). Что они собой представляют, если не анонимные классы, как определено?
что, если вы измените void localTest() на возврат MyInterface, вы просто опубликуете переменную, которая ссылается на ваш анонимный класс, даже если к ссылке можно получить доступ вне вашего метода. Таким образом, класс по-прежнему анонимный - он локальный, поскольку у вас не может быть других экземпляров этого класса. Итак, класс локальный (объект не нужен)
То, что вы показываете, - это не местный класс.
@LuiggiMendoza Нет, локальный класс определяется отдельно от своего создания, оба показанных примера являются простыми анонимными классами. У местных классов есть собственное название.
Когда вы добавляете инициализатор поля в определение поля, вы фактически добавляете строку кода в конструктор по умолчанию. Я предполагаю, что если вы посмотрите на скомпилированный код, вероятно, анонимный класс будет связан с методом конструктора.
@MarkRotteveel, спасибо за комментарий, не могли бы вы указать мне на источник, в котором говорится, что локальный класс должен иметь имя / не может быть анонимным, поскольку это не было моим пониманием. Спасибо!
Как и все эти вещи, посмотрите спецификацию языка Java, в частности, 14.3. Объявления локальных классов говорит: «Локальный класс - это вложенный класс (§8 (Классы)), который не является членом какого-либо класса и имеет имя (§6.2, §6.7)».
@MarkRotteveel - спасибо за это, я смотрел документы, кто знает сколько раз, и никогда не сталкивался с этим раньше.




Локальные классы определены как здесь как определяемые в блокировать, а не в методе. Ваш пример все еще анонимный класс. Если вы находитесь в процессе обучения, обратите внимание, что вы можете фактически заменить объявление лямбда-выражением, например:
MyInterface mi = () -> System.out.println("test");
Кроме того, анонимные классы описываются только как локальные классы нравиться, что означает, что первые не обязательно являются подмножеством вторых.
Хммм ... Хорошо, спасибо, @A.Bandtock. Мы действительно включаем здесь фигурные скобки класса, если да, не могли бы вы помочь мне понять, почему у нас есть термины «внутренний класс» и «локальный класс», когда это будет означать, что все внутренние классы являются локальными классами (если я не ошибаюсь) - кажется немного лишним ... спасибо - просто пытаюсь понять мою терминологию :-)
@Zippy Локальные классы - это внутренние классы, но нестатические классы, вложенные внутри другого класса, являются внутренними классами также (и они гораздо более распространены, чем локальные классы). См. 8.1.3. Внутренние классы и закрывающие экземпляры.
@Zippy Если вы читаете ссылку там, она фактически дает вам определение блока как «который представляет собой группу из нуля или более операторов между сбалансированными фигурными скобками», что в основном переводится как «что-то между { и }. Все локальные классы являются внутренними классами, различие таково, как описано в @Mark Rotteveel.
Я знаю, что все локальные классы являются внутренними классами, но это также означает, что все внутренние классы также являются локальными классами, правильно?
@Zippy Согласно ответам здесь: stackoverflow.com/questions/10392725/… моя интерпретация документации кажется неправильной ... Для хорошей сводной проверки здесь: docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html
@Zippy По словам docs.oracle.com/javase/tutorial/java/javaOO/nested.html, «Есть два особых типа внутренних классов: локальные классы и анонимные классы». Это говорит о том, что все внутренние классы могут быть помещены в одну из этих категорий, что указывает на то, что моя первоначальная интерпретация была верный. В любом случае семантика этого позволяет использовать «внутренний класс» в любой ситуации.
Нет, это неверное толкование. У вас есть внутренние классы (нестатические классы, определенные внутри другого класса), и небольшое подмножество внутренних классов («особые виды») - это локальные классы и анонимные классы; все остальные - «нормальные» внутренние классы.
Оба примера, которые вы показываете, являются анонимными классами. Настоящий локальный класс - это определение класса в методе (или другом блоке кода) с фактическим именем (то есть не анонимным). Учитывая ваш пример, эквивалентный локальный класс будет:
public void localTest(){
class LocalClass implements MyInterface {
@Override
public void test(){
System.out.println("test");
}
}
MyInterface mi = new LocalClass();
}
На мой взгляд, вам вряд ли когда-нибудь понадобится местный класс. Думаю, я попытался использовать его только один раз, чтобы быстро реорганизовать его только тогда, когда я понял, что мне действительно нужно.
Наиболее важное различие между локальными классами и анонимными классами заключается в том, что вы можете повторно использовать локальный класс в одном методе (то есть создавать несколько экземпляров в одном методе, не прибегая к циклам или лямбдам).
Кроме того, поскольку у вас действительно есть определение класса, вы также можете определять и вызывать методы, которые не определены в интерфейсе или суперклассе. До Java 10 и появления var это было невозможно с анонимными классами.
Другие незначительные отличия заключаются в том, что локальные классы могут быть абстрактными или окончательными, а локальные классы могут расширять (и расширяться) другими локальными классами, в то время как анонимный класс не является окончательным и не может быть абстрактным, но анонимные классы не могут быть расширены другими классами.
Для получения дополнительной информации о различиях между локальными классами и анонимными классами см. Спецификацию языка Java, в частности 14.3. Объявления локальных классов и 15.9.5. Объявления анонимных классов и связанные разделы.
Очень хорошее указание на то, что редко (если вообще когда-либо) нужно использовать локальные классы. Они усложняют и ухудшают ремонтопригодность. Стоит отметить, что анонимные классы, наоборот, могут быть чрезвычайно полезными.
@ A.Bandtock Если честно, поскольку Java 8 и методы обрабатывают, я считаю, что мне также редко нужно использовать анонимные классы.
Спасибо, я пытаюсь понять правильную терминологию для экзамена OCP. А также просто потому, что мне просто нравится знать правильную терминологию. Это просто сбивает с толку, потому что анонимные классы описываются как «как локальные классы, но без имени».
Это потому, что они являются локальными классами нравиться, но у них нет имени. Быть нравиться чем-то не означает, что это то же самое.
Действительно, @MarkRotteveel, но он также говорит: «Они похожи на локальные классы, за исключением того, что у них нет имени. Используйте их, если вам нужно использовать локальный класс только один раз, они упоминают локальные классы очень конкретно.
Важная фраза - только один раз. Как я конкретно упоминал в своем ответе, если у вас есть локальный класс, вы можете new несколько раз в разных частях вашего метода, а не с анонимным классом. Если вы new анонимный класс несколько раз в разных частях одного и того же метода, вы фактически используете два разных анонимных класса. Тем не менее, не зацикливайтесь на этом, местные классы - очень эзотерическая особенность (в большей степени, чем анонимные классы), и вы вряд ли когда-нибудь увидите их в реальной жизни.
Это все еще анонимные классы. То, что вы показали, не является определением, это объяснение - обратите внимание на часть локальных классов нравиться. Даже анонимный класс, используемый в объявлении поля, является нравиться локальным классом.