Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. PHP последовательно сравнивает (в порядке объявления) свойства объекта и останавливается при первом найденном свойстве неравенства. Это поведение не задокументировано, поэтому о грустном упоминании об этом трудно сказать, кроме как смотреть на источник PHP.
Не документировано, как правило, синоним «не полагайтесь на него».
Точное поведение определено в спецификации языка PHP , поэтому вы можете положиться на него.
[...], если объекты имеют разные типы, результат сравнения FALSE. Если объекты одного типа, свойства объектов сравниваются с [sic] , используя описанное выше сравнение массива.
blockquote>И сравнение массива определено следующим образом:
[...] Для массивов с одинаковыми числами элементов ключи из левого операнда рассматриваются один за другим, если следующая клавиша в левом операнде существует в правого операнда сравниваются соответствующие значения. Если они неравны, массив, содержащий меньшее значение, считается меньше, чем другой, и сравнение заканчивается; в противном случае процесс повторяется со следующим элементом. [...] Если все значения равны, то массивы считаются равными.
blockquote>Просто обменивайтесь каждым упоминанием массива с объектом и с свойством в вашем уме, и у вас есть точное описание того, как это работает. Я опустил бесполезные особенности массива в приведенной выше цитате.
Каждый класс в php имеет связанную структуру (в c-коде) функций обработчика, он выглядит как
struct _zend_object_handlers {
/* general object functions */
zend_object_add_ref_t add_ref;
zend_object_del_ref_t del_ref;
[...]
zend_object_compare_t compare_objects;
[...]
};
compare_objects
указывает на функцию, которая «принимает два объекта» и возвращает - 1,0,1 в соответствии с тем, что этот компаратор определяет как порядок (как и strcmp () для строк). Эта функция используется только тогда, когда оба операнда (объекты) указывают на одну и ту же функцию сравнения, но давайте просто придерживаться этого случая. Вот где, например, DateTime
«добавляет» свою функцию для сравнения двух экземпляров DateTime, она просто определяет другую, специфичную для DateTime функцию compare_objects
и помещает ее в структуру, описывающую его класс.
static void date_register_classes(TSRMLS_D)
{
[...]
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
ce_date.create_object = date_object_new_date;
[...]
date_object_handlers_date.compare_objects = date_object_compare_date;
Итак, если вы хотите (точно), как сравниваются два экземпляра DateTime, посмотрите на date_object_compare_date
.
Сравнение , описанное в руководстве (по крайней мере для случая cmp (o1, o2) == 0), как представляется, реализовано в zend_std_compare_objects
. И он используется как StdClass, так и простым пользовательским классом, например,
<?php
class Foo { }
$a = new StdClass;
$b = new Foo;
$a > $b;
. Но другие классы (в php-расширениях) устанавливают другие функции. DateTime, ArrayObject, PDOStatement, даже Closures используют разные функции. Но я не нашел способ определить функцию / метод сравнения в коде скрипта (но не слишком сильно / долго)
DateTime
- действительно, я изучил внутреннюю реализацию (так, как вы уже писали)
– Alma Do
20 March 2014 в 12:21
DateTime
). – user703016 20 March 2014 в 11:52