Как указано BalusC, actionListener
по умолчанию использует исключение, но в JSF 2.0 есть немного больше. А именно, он не просто проглатывает и записывает журналы, а фактически публикует исключение.
Это происходит с помощью такого вызова:
context.getApplication().publishEvent(context, ExceptionQueuedEvent.class,
new ExceptionQueuedEventContext(context, exception, source, phaseId)
);
Слушателем по умолчанию для этого события является ExceptionHandler
, который для Моджары установлен на com.sun.faces.context.ExceptionHandlerImpl
. Эта реализация в основном отменяет любое исключение, за исключением случаев, когда это относится к исключению AbortProcessingException, которое регистрируется. ActionListeners обертывают исключение, которое генерируется клиентским кодом в таком AbortProcessingException, которое объясняет, почему они всегда регистрируются.
Этот ExceptionHandler
может быть заменен, однако, в faces-config.xml с пользовательской реализацией:
<exception-handlerfactory>
com.foo.myExceptionHandler
</exception-handlerfactory>
Вместо того, чтобы слушать глобально, один компонент может также слушать эти события. Ниже приведено доказательство этой концепции:
@ManagedBean
@RequestScoped
public class MyBean {
public void actionMethod(ActionEvent event) {
FacesContext.getCurrentInstance().getApplication().subscribeToEvent(ExceptionQueuedEvent.class, new SystemEventListener() {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
ExceptionQueuedEventContext content = (ExceptionQueuedEventContext)event.getSource();
throw new RuntimeException(content.getException());
}
@Override
public boolean isListenerForSource(Object source) {
return true;
}
});
throw new RuntimeException("test");
}
}
(обратите внимание: это не то, как обычно нужно кодировать слушателей, это только для демонстрационных целей!) [/ G0]
Вызов этого из Facelet следующим образом:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<h:form>
<h:commandButton value="test" actionListener="#{myBean.actionMethod}"/>
</h:form>
</h:body>
</html>
Будет отображаться страница с ошибкой.
Обычная array
распадается на указатель на свой первый элемент, он равен &array[0]
. Первый элемент также начинается с того же адреса, что и сам массив. Отсюда &array == &array[0]
.
Но важно отметить, что типы различны:
&array[0]
(в вашем примере) int*
. &array
- int(*)[5]
. Отношения между &array[0]
и &array
могут быть проще, если я покажу это немного «графически» (с добавленными указателями):
+----------+----------+----------+----------+----------+ | array[0] | array[1] | array[2] | array[3] | array[4] | +----------+----------+----------+----------+----------+ ^ | &array[0] | &array
Вещи разные с указателями, хотя. Указатель pArray
указывает на некоторую память, значение pArray
- это местоположение этой памяти. Это то, что вы получаете, когда используете pArray
. Это также как &pArray[0]
.
Когда вы используете &pArray
, вы получаете указатель на указатель . То есть вы получаете местоположение (адрес) самой переменной pArray
. Его тип int**
.
Несколько графически с указателем pArray
было бы что-то вроде этого
+--------+ +-----------+-----------+-----------+-----------+-----------+-----+ | pArray | ----> | pArray[0] | pArray[1] | pArray[2] | pArray[3] | pArray[4] | ... | +--------+ +-----------+-----------+-----------+-----------+-----------+-----+ ^ ^ | | &pArray &pArray[0]
[Обратите внимание на ...
в конце «массива», потому что указатели не сохраняют информацию о памяти, на которую он указывает. Указатель указывает только на определенное место, «первый» элемент «массива». Обрабатывать память как «массив» - дело программиста.]
Массив X должен вести себя как указатель на непрерывный список X в памяти, так же, как указатель. Однако нигде не написано, где память, в которой хранятся эти данные, должна иметь собственный адрес и возможность записи. В случае явного указателя существует новое выделение для этого адреса (в данном случае стека), однако для массива в стеке компилятор уже знает, где находится содержимое, поэтому новое выделение не требуется.
Как следствие, небезопасно рассматривать его как указатель без индексации. например :
pArray = nullptr; // This is a memory leak, unless a copy is taken, but otherwise fine.
array = nullptr; // This is will make the compiler upset