Почему `& amp; массив` и` массив` указывают на один и тот же адрес?

Как указано 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>

Будет отображаться страница с ошибкой.

51
задан Koray Tugay 21 February 2019 в 16:39
поделиться

2 ответа

Обычная 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]

[Обратите внимание на ... в конце «массива», потому что указатели не сохраняют информацию о памяти, на которую он указывает. Указатель указывает только на определенное место, «первый» элемент «массива». Обрабатывать память как «массив» - дело программиста.]

0
ответ дан Some programmer dude 21 February 2019 в 16:39
поделиться

Массив 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
0
ответ дан ANone 21 February 2019 в 16:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: