Java 8 начала появляться, принося новую функцию: используйте Lambda Expression (JSR-335) для функционального программирования. Сегодня мы собираемся обсудить часть Lambda: виртуальное расширение, также известное как метод защитника. Эта функция позволяет реализовать метод предоставления методов в определении интерфейса. Например, вы можете определить метод для существующих интерфейсов (например, список и карта), чтобы другим разработчикам не нужно было перестроить эти методы, что немного похоже на абстракцию, но на самом деле это интерфейс. Конечно, Java 8 теоретически совместим с существующими библиотеками.
Метод виртуального расширения привносит множественные характеристики наследования в Java. Возможно, вы можете увидеть тень множественного наследства через эту функцию. Но вы все равно можете имитировать наследование состояния экземпляра. Я опишу наследство государства через Mixin в следующей статье подробно.
Что смешано в микшине?
Смешивание -это абстрактный класс комбинации. Например, если у вас есть класс, чтобы указать «лошадь», вы можете создать экземпляр этого класса, чтобы создать пример «лошади», а затем расширить его, как «Гараж» и «Сад».
Val myhouse = новый дом с гаражом с садом
Из наследования микшина не является конкретной спецификацией, это просто метод, который используется для добавления различных функций к существующим категориям. В ООП, с микшином, у вас есть читабельность класса через него.
Например, в модуле SocketServer есть метод Mixin.
Class WorkingPserver (WorkingMixin, UDPServer): PassClass WOTKINGTCPSERVER (WOTKINGMIXIN, TCPSERVER): PASS CLASS THITEUDPERPERVER (THITEMIXIN): PassClass ThinkingTcpserver (ThreadingMixin, TCPServer): Pass
Что такое метод виртуального расширения?
Java 8 представит концепцию виртуального расширения, также называемого методом публичного защитника.
VEM стремится предоставить метод по умолчанию для интерфейса Java. Такая третья частичная библиотека, такая как Hibernate, не должна повторять все методы этих API сбора, потому что она обеспечила некоторые методы по умолчанию.
Ниже приведен пример того, как определить метод в интерфейсе:
Общедоступная интерфейсная коллекция
Смешанная симуляция Java 8
Теперь мы приходим к достижению смешанного эффекта через VEM, но заранее предупреждение: пожалуйста, не используйте на работе!
Следующая реализация не является безопасной поток, и может быть проблема утечки памяти, которая зависит от хешкода и равенства методами, которые вы определили в классе.
Прежде всего, мы определяем определение метода (смоделированное статусное бобы) и предоставляем метод:
Общедоступный интерфейс SwitchableMixin {boolean isActivated () default {return Switchables.Isactivated (this);} void setActivativated (логическая активность) Bull {switchables.SetActivated (this, activated);}}
Затем мы определяем класс инструментов, который содержит экземпляр карты, чтобы сохранить ассоциацию экземпляров и статуса.
Общедоступный класс Switchables {Private Static Final Map <SwitchableMixin, SwitchAbledEviceState> Switch_states = New Hashmap <() (); Activity;} public void setActivated (DefficeBultemixin, Boolean Activated) {SwitchableDeviceState = Switch_states.get (Device); .Activated = Activated;} private Static Class SwitchAbledEviceState {Private Boolean Activated;}}
Вот вариант использования, который подчеркивает наследование государства:
Приватное статическое устройство класса {} частный статический класс Devicea Extends Device Imprements SwitchableMixin {} Private State Class DeviceB Extends Device Implectemixin {}
"Совершенно разные вещи"
Вышеуказанная реализация кажется нормальной, но архитектор Java Java's Java Java Брайан Гетц задал мне вопрос о том, что текущая реализация не может работать (при условии, что безопасность потока и утечка памяти была решена)
Интерфейс FakeBrokenmixin {Статический карта <fakebrokenmixin, String> BackingMap = Collections. put (this, name);}} интерфейс x extends runnable, fakebrokenmixin {} x makex () {return () -> {System.println ("x");}; ();
Какой результат вы догадаетесь, этот код будет отображаться после выполнения?
Решение сомнения
На первый взгляд, нет проблем с этим кодом реализации. X - это интерфейс, который содержит только один метод, потому что GetName и SetName уже имеют определение по умолчанию, но метод выполнения запускаемого интерфейса не определяется. Реализация метода запуска. Следовательно, результат, который вы хотите этой программы после исполнения, состоит в том, чтобы:
X1x2
Если вы удалите вызов метода GetName, то результат выполнения становится:
MyTest $ 1@30ae8764mytest $ 1@123acf34
Эти две строки показывают, что выполнение метода Makex происходит из двух разных экземпляров, и в настоящее время генерируется текущий OpenJDK 8 (здесь я использую OpenJDK 8 24.0-B07).
В любом случае, текущий OpenJDK 8 не отражает окончательное поведение Java 8.
X2x2
Если вы не вызовите метод GetName, он будет отображаться:
Mytest $ $ $ lambda $ 1@5506d4eamytest $ $ $ lambda $ 1@5506d4ea
Каждый метод Makex, по -видимому, является экземпляром одиночной, из одного и того же анонимного внутреннего класса.
Поскольку во время компиляции выражение Lambda не подвергалось полному переводу. Эта инструкция содержит всю необходимую мета -информацию о выражении Labda во время выполнения. Включая имя метода, тип ввода и вывода, а также метод под названием Bootstrap. Метод начальной загрузки используется для определения экземпляра получения этого метода.
Вернемся к вопросу только сейчас, выражение лямбда превратилось в частный статический метод, () -> {System.out.println ("x");} был перенесен на MyTest:
Private Static void Lambda $ 0 () {System.out.println ("x");}
Если вы используете Provate Parameter с устройством встречного компиляции Javap, и вы можете увидеть этот метод, вы также можете использовать параметр -c для просмотра более полного преобразования.
Когда вы запускаете программу, JVM вызывает метод метафакции Lambda, чтобы попытаться объяснить инструкции Invokedynamic. В нашем примере, когда Makex вызывает в первый раз, метод Lampda Metafactory генерирует экземпляр x и динамически связан метод выполнения с методом лямбды В памяти, поэтому экземпляр вашего второго вызова такой же, как и в первый раз.
Вы его ремонтировали? Есть решение?
Там нет прямого ремонта или решения этой проблемы. Хотя программа Oracle Java 8 Defaults-xdlambdatomethod, поскольку этот параметр не является частью спецификации JVM, реализация различных поставщиков и JVM отличается. Для выражения Lambda единственное, что вы можете ожидать, - это реализовать свой метод интерфейса в классе.
Другие методы
До сих пор, хотя наше подражание микшину не может быть совместимой с Java 8, все еще возможно добавить несколько сервисов с помощью множественного наследства и назначения. Этот метод является виртуальным шаблоном поля (режим виртуального поля).
Так что посмотрите на наш переключаемый.
Интерфейс переключен {boolean isactive ();
Нам нужен переключаемый интерфейс, и мы предоставим дополнительный метод абстракции для возврата к переключению реализации. Интегрированный метод содержит определение по умолчанию.
Общедоступный интерфейс Extends Extends {Switchable GetSwitchable ();
Далее мы создаем полную переключаемую реализацию:
Public Class SwitchableImpl реализует Switchable {Private Boolean Active;
Это пример нашего режима виртуального поля:
Общедоступный класс {} открытый класс Devicea Extends Device реализует SwitchableView {private SwitchableImpl (); Switchable GetSwitchable () {return Switchable;}}
в заключение
В этой статье мы используем два метода для добавления нескольких сервисов с помощью метода виртуального расширения Java 8. Первый метод использует карту для хранения состояния экземпляра. Другим методом является использование режима виртуального поля для возврата окончательного примера реализации через абстрактный Getter. Второй метод более независим и безопаснее.
Метод виртуального расширения -это новая особенность Java.