Самое быстрое (не внутреннее / неассемблерное) решение для этого - найти младший байт, а затем использовать этот байт в таблице поиска с 256 входами. Это дает вам худшую производительность четырех условных инструкций и наилучшего варианта 1. Это не только наименьшее количество инструкций, но и наименьшее количество ветвей, что очень важно для современного оборудования.
Ваша таблица (256 8-разрядных записей) должна содержать индекс LSB для каждого номера в диапазоне 0-255. Вы проверяете каждый байт своего значения и находите самый младший ненулевой байт, затем используйте это значение для поиска реального индекса.
Для этого требуется 256-байтовая память, но если скорость этой функции равна так важно, чтобы 256-байты это достойно,
Например
byte lowestBitTable[256] = {
.... // left as an exercise for the reader to generate
};
unsigned GetLowestBitPos(unsigned value)
{
// note that order to check indices will depend whether you are on a big
// or little endian machine. This is for little-endian
byte* bytes = (byte*)value;
if (bytes[0])
return lowestBitTable[bytes[0]];
else if (bytes[1])
return lowestBitTable[bytes[1]] + 8;
else if (bytes[2])
return lowestBitTable[bytes[2]] + 16;
else
return lowestBitTable[bytes[3]] + 24;
}
Две или более аннотации одного типа не допускаются. Однако вы можете сделать что-то вроде этого:
public @interface Foos {Foo [] value (); } @Foos ({@ Foo (bar = "one"), @Foo (bar = "two")}) public void haha () {}
Вам понадобится специальная обработка аннотации Foos в коде.
btw, я только что использовал это 2 часа назад для решения одной и той же проблемы:)
Помимо других упомянутых способов, в Java8 есть еще один более подробный способ:
@Target (ElementType.TYPE) @Repeatable (FooContainer.class) @Retention (RetentionPolicy.RUNTIME ) @interface Foo {Строковое значение (); } @Target (ElementType.TYPE) @Retention (RetentionPolicy.RUNTIME) @interface FooContainer {Foo [] value (); } @Foo ("1") @Foo ("2") класс @Foo ("3") Пример {}
Пример по умолчанию получает, FooContainer
в качестве аннотации
Arrays.stream (Example.class.getDeclaredAnnotations ()). forEach (System.out :: println); System.out.println (Example.class.getAnnotation (FooContainer.class));
Оба вышепечатаемых:
@ com.FooContainer (значение = [@ com.Foo (значение = 1), @ com.Foo (значение = 2), @ com.Foo (значение = 3)])
@ com.FooContainer (значение = [@ com.Foo (значение = 1), @ com.Foo (значение = 2), @ com.Foo (значение = 3)])
blockquote>
Как сказал sfussenegger, это невозможно.
Обычным решением является создание «множественной» аннотации, которая обрабатывает массив предыдущей аннотации.
Кстати, это очень удобно использовать в крупных публичных проектах (например, Hibernate), поэтому его нельзя рассматривать как взломать, но это скорее правильное решение для этой потребности.
В зависимости от ваших потребностей было бы лучше, если бы ваша более ранняя аннотация обрабатывала несколько значений.
Пример:
public @interface Foo {String [] bars (); }
объединение других ответов в простейшую форму ... аннотация с простым списком значений ...
@Foos ({"one", "two"}) private String AWK; // ... public @interface Foos {String [] value (); }
В Java 8 (выпущен в марте 2014 года) можно писать повторяющиеся / дублированные аннотации. См. [D0] http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html .
Если у вас есть только один параметр «bar», вы можете назвать его «значение». В этом случае вам не обязательно писать имя параметра вообще, когда вы его используете следующим образом:
@Foos ({@ Foo ("one"), @Foo ("two")} ) public void haha () {}
немного короче и аккуратно, imho ..
http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
Начиная с Java8 вы можете описать повторяемые аннотации:
@Repeatable (FooValues.class) public @interface Foo {String bar (); } public @interface FooValues {Foo [] value (); }
Примечание, значение
является обязательным для списка значений.
Теперь вы можете использовать аннотации, повторяя их вместо заполнения массива: [ ! d7]
@Foo (bar = "one") @Foo (bar = "two") public void haha () {}
@Foos ([@ Foo (bar = «one»), @Foo (bar = «two»)])
. См. [D0] groovy.codehaus.org/Annotations+with+Groovy – sfussenegger 11 January 2012 в 15:29