NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Они эквивалентны из стандартного (основное внимание) (7.1.3.2):
Имя typedef также может быть введено с помощью объявления alias. Идентификатор, следующий за ключевым словом using, становится typedef-name и необязательным атрибутом-спецификатором-seq, следующим за идентификатором, к этому typedef-name. Он имеет ту же семантику, как если бы он был введен спецификатором typedef. В частности, он не определяет новый тип и не должен отображаться в идентификаторе типа.
blockquote>
Синтаксис использования имеет преимущество при использовании в шаблонах. Если вам нужна абстракция типа, но также необходимо сохранить параметр шаблона, который можно будет указать в будущем. Вы должны написать что-то вроде этого.
template <typename T> struct whatever {};
template <typename T> struct rebind
{
typedef whatever<T> type; // to make it possible to substitue the whatever in future.
};
rebind<int>::type variable;
template <typename U> struct bar { typename rebind<U>::type _var_member; }
Но использование синтаксиса упрощает этот прецедент.
template <typename T> using my_type = whatever<T>;
my_type<int> variable;
template <typename U> struct baz { my_type<U> _var_member; }
Они по существу одинаковы, но using
обеспечивает alias templates
, что весьма полезно. Один хороший пример, который я мог найти, следующий:
namespace std {
template<typename T> using add_const_t = typename add_const<T>::type;
}
Итак, мы можем использовать std::add_const_t<T>
вместо typename std::add_const<T>::type
Они в основном одинаковы, за исключением того, что
The alias declaration is compatible with templates, whereas the C style typedef is not.
using
представляется надмножествомtypedef
. Тогда будет лиtypdef
устаревать в будущем? – iammilind 25 May 2012 в 05:28using
именно потому, что семантикаtypedef
плохо работала с шаблонами. Что-то противоречит тому факту, чтоusing
определяется как одна и та же семантика. – celtschk 21 July 2013 в 10:44n1489
. Алиас шаблона not - псевдоним для типа, но псевдоним для группы шаблонов. Чтобы провести различие междуtypedef
, почувствовал необходимость в новом синтаксисе. Кроме того, имейте в виду, что вопрос OP о разнице между версиями без шаблонов. – Jesse Good 21 July 2013 в 23:19