Примером этого исключаемого исключения является: Когда вы пытаетесь проверить что-то, это null.
Например:
string testString = null; //Because it doesn't have a value (i.e. it's null; "Length" cannot do what it needs to do)
if (testString.Length == 0) // Throws a nullreferenceexception
{
//Do something
}
Время выполнения .NET исключение NullReferenceException при попытке выполнить действие над чем-то, что не было инстанцировано, т.е. код выше.
По сравнению с ArgumentNullException, которое обычно выбрано как защитная мера, если метод ожидает, что то, что происходит
Дополнительная информация находится в C # NullReferenceException и Null Parameter .
Обработка аннотации неверна для вас, из Wikipedia :
Когда исходный код Java скомпилирован, аннотации могут обрабатываться подключаемыми модулями компилятора обработчики аннотаций. Процессоры могут создавать информационные сообщения или создавать дополнительные исходные файлы или ресурсы Java, которые, в свою очередь, могут быть скомпилированы и обработаны, но обработчики аннотаций не могут изменять сам аннотированный код.
blockquote>Люди предложили вам правильный путь - АОП. В частности, вы можете использовать AspectJ. «Быстрый результат» - это (если вы используете Eclipse):
1) Установите AJDT (инструменты разработки AspectJ) 2) Создайте проект AspectJ и добавьте туда свои классы и аннотации 3) Create Aspect:
public aspect Processor { private StaticReference z; pointcut generic() // intercept execution of method named test, annotated with @Anno1 // from any class type, annotated with @Anno2 : execution(@Anno2 * (@Anno1 *).test()) // method takes no arguments && args (); // here you have write what you want method actually does void around () : generic() { z.invokeToAll(); } }
теперь вы можете выполнить тест, и вы увидите, что он работает;) AJDT автоматически компилирует код для вас, поэтому не нужно выполнять какую-либо ручную работу, надейтесь, что это то, что вы назвали «magic»;)
UPDATE:
, если ваш метод в методе test () зависит от значения аннотации Anno1, то внутри аспект вы можете получить аннотацию класса, для которой она выполняется таким образом :
void around () : generic() { Annotation[] classAnnotations = thisJoinPoint.getThis().getClass().getAnnotations(); String ArgumentValue = null; for ( Annotation annotation : classAnnotations ) { if ( annotation instanceof Anno1 ) { ArgumentValue = ((Anno1) annotation).Argument(); break; } } if ( ArgumentValue != null && ArgumentValue.equals("Option1")) { z.invokeToAll(); } }
, где thisJoinPoint является специальной ссылочной переменной.
UPDATE2:
, если вы хотите добавить
System.out.println( this )
в вашем аспекте вам нужно написать тамSystem.out.println( thisJoinPoint.getThis() )
, просто протестировать, и он работает.thisJoinPoint.getThis()
возвращает вас «это», но не совсем; на самом деле это переменная Object, и если вы хотите получить какую-либо информацию, вам нужно либо бросить, либо использовать отражение. ИthisJoinPoint.getThis()
не предоставляет доступ к частной собственности.Ну, теперь кажется, что на ваш вопрос ответили, но если я пропустил что-либо, или вы получите дополнительный вопрос / проблемы таким образом - не стесняйтесь спрашивать ;)
Я вообще не уверен, возможно ли изменить исходный или байтовый код с помощью аннотаций. Из того, что вы описываете, похоже, что аспектно-ориентированное программирование может обеспечить решение вашей проблемы.
Ваши аннотации довольно похожи на концепцию pointcut (они отмечают местоположение, где необходимо вставить код), а вставленный код закрывает совет concept.
Другим подходом был бы анализ исходного файла java в абстрактное синтаксическое дерево, изменение этого AST и сериализация на вход компилятора java.
Ну, вы можете увидеть, будет ли полезен следующий код шаблона:
public void magic(Object bean, String[] args) throws Exception {
for (Method method : bean.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Anno2.class)) {
// Invoke the original method
method.invoke(bean, args);
// Invoke your 'z' method
StaticReference.invokeAll();
}
}
}
. В качестве альтернативы вы можете использовать аспектно-ориентированное программирование, например, у вас есть AspectJ проект.
Если ваш класс расширяет подходящий интерфейс, вы можете обернуть его в DynamicProxy, который делегирует все вызовы исходным методам, кроме вызова для тестирования.
Совершенно возможно делать то, что вы просите, хотя есть оговорка: полагаться на частные API-интерфейсы компилятора. Звучит пугающе, но на самом деле это не так (реализация компилятора имеет тенденцию быть стабильной).
Существует статья, объясняющая процедуру: Руководство Hacker для Javac .
Примечательно, что это используется Project Lombok для обеспечения автоматической генерации геттера / сеттера (между прочим). в следующей статье объясняет, как это происходит, в основном повторное повторение того, что сказано в вышеупомянутой статье.