Возможно ли статическое метапрограммирование в Java?

StackOverflow https://stackoverflow.com/questions/112320

  •  02-07-2019
  •  | 
  •  

Вопрос

Я являюсь поклонником статическое метапрограммирование в C++.Я знаю, что в Java теперь есть дженерики.Означает ли это, что статическое метапрограммирование (т. е. выполнение программы во время компиляции) возможно в Java?Если да, то может ли кто-нибудь порекомендовать какие-нибудь хорошие ресурсы, где можно узнать об этом больше?

Это было полезно?

Решение

Нет, это невозможно.Дженерики не так эффективны, как шаблоны.Например, аргументом шаблона может быть пользовательский тип, примитивный тип или значение;но общим аргументом шаблона может быть только Object или его подтип.

Редактировать:Это старый ответ;с 2011 года у нас есть Java 7, которая имеет Аннотации, которые могут быть использованы для такого обмана.

Другие советы

Взгляните на Clojure ( Клоджур ).Это LISP с макросами (meta-programming), который работает в JVM и очень совместим с Java.

Что именно вы подразумеваете под "статическим метапрограммированием"?Да, метапрограммирование шаблонов C ++ в Java невозможно, но оно предлагает другие методы, гораздо более мощные, чем методы из C ++:

  • отражение
  • аспектно-ориентированное программирование (@AspectJ)
  • манипулирование байт-кодом (Javassist, ObjectWeb ASM, Java-агенты)
  • генерация кода (инструмент обработки аннотаций, шаблонизаторы, такие как Velocity)
  • Манипуляции с абстрактным синтаксическим деревом (API, предоставляемые популярными IDE)
  • возможность запуска компилятора Java и использования скомпилированного кода даже во время выполнения

Лучшего метода не существует:каждый из этих методов имеет свои сильные и слабые стороны.Благодаря гибкости JVM, все эти методы в Java могут использоваться как во время компиляции, так и во время выполнения.

Нет.Более того, универсальные типы стираются компилятором до их верхней границы, поэтому вы не можете создать новый экземпляр универсального типа T во время выполнения.

Лучший способ выполнить метапрограммирование на Java - это обойти удаление типа и передать Class<T> объект вашего типа T.Тем не менее, это всего лишь взлом.

Нет, дженерики в Java - это чисто способ избежать приведения объекта.

Если вам нужна мощная логика времени компиляции для Java, один из способов сделать это - с помощью какой-либо генерации кода.Поскольку, как указывали другие постеры, язык Java не предоставляет никаких функций, подходящих для выполнения логики времени компиляции, это может быть вашим лучшим вариантом (если вам действительно нужна логика времени компиляции).Как только вы исчерпаете другие возможности, и вы конечно если вы хотите заниматься генерацией кода, вас может заинтересовать мой проект с открытым исходным кодом Rjava, доступный по адресу:

http://www.github.com/blak3mill3r

Это библиотека генерации кода Java, написанная на Ruby, которую я написал для того, чтобы автоматически генерировать интерфейсы Google Web Toolkit для приложений Ruby on Rails.Это оказалось весьма кстати для этого.

В качестве предупреждения, отлаживать код Rjava может быть очень сложно, Rjava мало что проверяет, она просто предполагает, что вы знаете, что делаете.В любом случае, это в значительной степени состояние статического метапрограммирования.Я бы сказал, что это значительно проще в отладке, чем что-либо нетривиальное, выполняемое с помощью C ++ TMP, и его можно использовать для тех же целей.

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

Может быть, в очень ограниченном смысле?http://michid.wordpress.com/2008/08/13/type-safe-builder-pattern-in-java/

Ломбок предлагает слабую форму метапрограммирования во время компиляции.Однако техника, которую они используют, является совершенно общий.

Видишь Преобразование кода Java во время компиляции для соответствующего обсуждения

Я не уверен, что понимаю преимущество статического метапрограммирования.

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

Я могу ошибаться на этот счет, я серьезно подумываю о том, чтобы задать вопрос по этому поводу, потому что я не уверен, что понимаю его.Похоже, что статическое метапрограммирование - это аккуратный взлом, который позволяет обойти тот факт, что некоторые языки не сохраняют много информации о времени компиляции, доступной во время выполнения (одна из сильных сторон Java и динамических языков).

Если бы кто-нибудь мог ответить ссылкой на пример, где метапрограммирование предлагает более понятное, читаемое или иным образом лучшее решение, чем это было бы при рефлексии, я был бы признателен за усилия.

Тот Самый Многообразный проект предлагает типо-сейф статический метапрограммирование для Java.Вы можете использовать его для динамического построения типов во время компиляции, поскольку Javac разрешает имена типов.Тот Самый Демонстрация схемы JSON демонстрирует статическое метапрограммирование в терминах динамического проектирования типов во время компиляции (без этапов сборки генерации кода).

Кроме того, вы можете использовать Manifold для добавления новых функций.Проверьте Структурная типизация, Расширения метода, и Типобезопасное Отражение. .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top