Каковы сходства и различия между аннотациями Java и атрибутами С#?
У меня есть библиотека Java, которую я рассматриваю, перенося на С#. Библиотека Java широко использует аннотации (как во время сборки, так и во время выполнения).
Я никогда не использовал атрибуты С#, но понимаю, что они являются грубым эквивалентом аннотаций Java.
Если я продолжу работу с портом, используя атрибуты для замены аннотаций, что мне нужно знать? Что будет? Другой? Что меня укусит?
Ответы
Ответ 1
Контроль, когда ваши метаданные становятся доступными, отличается между двумя языками.
Java предоставляет java.lang.annotation.Retention аннотацию и java.lang.annotation.RetentionPolicy enum для управления, когда метаданные аннотации доступны. Выбор варьируется от Runtime
(наиболее распространенных - метаданных аннотаций, сохраненных в файлах классов), до Source
(метаданные, отбрасываемые компилятором). Вы помечаете свой пользовательский интерфейс аннотаций, например:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.CLASS)
public @interface TraceLogging {
// etc
}
позволит вам задуматься о вашей пользовательской аннотации TraceLogging
во время выполнения.
С# использует атрибут ConditionalAttribute, который выводится из символов времени компиляции. Таким образом, аналогичный пример в С#:
[Conditional("TRACE")]
public class TraceLoggingAttribute : Attribute
{
// etc
}
который заставит компилятор выплевывать метаданные для вашего настраиваемого атрибута TraceLogging
, только если был определен символ TRACE
.
NB. метаданные атрибутов доступны во время выполнения по умолчанию в С# - это необходимо, только если вы хотите изменить это.
Ответ 2
Один важный аспект аннотаций Java, о котором я еще не рассмотрел подробно: вы можете написать код, который использует аннотации в javac (как я думаю, на Java 6) как форма метапрограммирования.
PostSharp позволяет что-то подобное, по общему признанию.
(Это далеко не единственное различие, но все это у меня есть время прямо сейчас.)
Ответ 3
Одно интересное отличие состоит в том, что С# допускает атрибуты уровня модуля и сборки. Они применяются к вашему модулю или сборке и доступны посредством отражения обычным способом. Java не дает отражения в файле jar, поэтому аннотации уровня jar невозможны.
На самом деле это довольно часто, как Visual Studio, файл с именем AssemblyInfo.cs
на уровне корневого проекта, который содержит, например:
[assembly: AssemblyVersionAttribute("1.2.3.4")]
[assembly: AssemblyTitleAttribute("My project name blah blah")]
...
В Java нет эквивалентной аннотации уровня jar (хотя, поскольку jdk5, существует немного используемый механизм аннотации уровня пакета - благодаря mmeyers для указания того, что один из них)
Ответ 4
Следуя за тем, что сказал Джон...
Оба Java 5 и Java 6 допускают метапрограммирование. Java 5 использует отдельный инструмент apt; Java 6 интегрирует его в компилятор. (Хотя Java 5 apt по-прежнему доступен на Java 6)
К сожалению, каждый использует другой API.
В настоящее время я использую API Java 5 для аннотаций Bean
См. http://code.google.com/p/javadude/wiki/Annotations для примера
(ПРИМЕЧАНИЕ. В настоящее время я делаю некоторые важные обновления, некоторые из которых меняют API.)
Очень классный материал...
- Скотт