Почему “пустой указатель” существует в C# и Java?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
73
задан Peter Mortensen 16 May 2016 в 22:17
поделиться

21 ответ

Anders Hejlsberg, "родительский элемент C#", просто говорил о той точке в его интервью Computerworld :

, Например, в системе типов у нас нет разделения между значением и ссылочными типами и nullability типов. Это может звучать как немного wonky или немного технический, но в ссылочных типах C# может быть пустым, таким как строки, но оценить типы, не может быть пустым. Уверенный было бы хорошо иметь не допускающие NULL-значения ссылочные типы, таким образом, Вы могли объявить, что строка ‘this никогда не может быть пустой, и я хочу, чтобы Вы компилятор проверили, что я никогда не могу поражать нулевого указателя here’.

50% ошибок, с которыми люди сталкиваются сегодня, кодируя с C# в нашей платформе и тем же, верны для Java в этом отношении, вероятно, исключения нулевой ссылки. Если бы у нас была более сильная система типов, которая позволила бы Вам говорить, что ‘this параметр никогда не может быть пустым, и Вы компилятор, проверьте это в каждом вызове путем выполнения статического анализа code’. Тогда мы, возможно, искореняли классы ошибок.

Cyrus Najmabadi, бывший инженер-разработчик программного обеспечения в команде C# (теперь работающий в Google) обсуждает на том предмете на его блоге: ( 1-й , 2-й , 3-й , 4-й ). Кажется, что самая большая помеха для принятия не допускающих NULL-значения типов - то, что нотация нарушила бы programmers’ привычки и кодовую базу. Что-то как 70% ссылок программ C#, вероятно, закончится как не допускающие NULL-значения.

, Если Вы действительно хотите иметь не допускающий NULL-значения ссылочный тип в C#, необходимо попытаться использовать Spec#, который является расширением C#, которые позволяют использование"!" как не допускающий NULL-значения знак.

static string AcceptNotNullObject(object! s)
{
    return s.ToString();
}
91
ответ дан Julien Hoarau 24 November 2019 в 12:09
поделиться

Пустой указатель является существенным требованием любого языка OO. Любая переменная объекта, которой не присвоили ссылка на объект, должна быть пустой.

-3
ответ дан David Arno 24 November 2019 в 12:09
поделиться

Обычно - NullReferenceException подразумевает, что некоторому методу не нравилось то, что это было вручено и возвратило нулевую ссылку, которая позже использовалась, не проверяя ссылку перед использованием.

, Что метод мог иметь thown некоторое более подробное исключение вместо того, чтобы возвратить пустой указатель, который выполняет сбой быстро способ мышления.

Или метод мог бы возвращать пустой указатель как удобство Вам, так, чтобы можно было записать , если вместо попытка и избегает "издержек" исключения.

0
ответ дан Amy B 24 November 2019 в 12:09
поделиться

Я делаю предложение:

  1. Пустой указатель Запрета
  2. Расширяют булевские переменные: Правда, Ложь и FileNotFound
0
ответ дан 24 November 2019 в 12:09
поделиться

При создании объекта с переменной экземпляра, являющейся ссылкой на некоторый объект что значение было бы Вы предлагать иметь эту переменную перед присвоением какой-либо ссылки на объект на него?

0
ответ дан Mecki 24 November 2019 в 12:09
поделиться

Помимо ВСЕХ причин, уже упомянутых, ПУСТОЙ УКАЗАТЕЛЬ необходим при необходимости в заполнителе для еще созданного объекта. Например. если у Вас есть циклическая ссылка между парой объектов, то необходимо аннулировать, так как Вы не можете инстанцировать обоих одновременно.

class A {
  B fieldb;
}

class B {
  A fielda;
}

A a = new A() // a.fieldb is null
B b = new B() { fielda = a } // b.fielda isnt
a.fieldb = b // now it isnt null anymore

Редактирование: можно быть в состоянии вытащить язык, который работает без пустых указателей, но это определенно не будет объектно-ориентированный язык. Например, пролог не имеет нулевых значений.

1
ответ дан Santiago Palladino 24 November 2019 в 12:09
поделиться

Я удивлен, что никто не говорил о базах данных для их ответа. Базы данных имеют nullable поля, и любой язык, который будет получать данные из DB, должен обработать это. Это означает иметь нулевое значение.

На самом деле, это столь важно, что для основных типов как интервал можно сделать их nullable!

Также рассматривают возвращаемые значения от функций, чем, если Вы хотели иметь функциональное деление, пара чисел и знаменателя могла бы быть 0? Единственный "корректный" ответ в таком случае был бы пустым. (Я знаю в таком простом примере, исключением, вероятно, был бы более оптимальный вариант..., но могут быть ситуации, где все значения корректны, но допустимые данные могут произвести недопустимый или неизмеримый ответ. Не уверенный исключение должно использоваться в таких случаях...)

1
ответ дан CodeRedick 24 November 2019 в 12:09
поделиться

Я не могу говорить с Вашим конкретным вопросом, но он кажется, что проблемой не является существование пустого указателя. Пустой указатель существует в базах данных, Вам нужен некоторый способ составлять это на прикладном уровне. Я не думаю, что это - единственная причина, она существует в .net, заметьте. Но я полагаю, что это - одна из причин.

1
ответ дан peacedog 24 November 2019 в 12:09
поделиться

Пустой указатель, поскольку это доступно в C#/C ++/Java/Ruby, лучше всего рассматривается как причуда немного неясных прошлый (Алгол), который так или иначе выжил по сей день.

Вы используете его двумя способами:

  • Для объявления ссылок, не инициализируя их (плохо).
  • Для обозначения возможностей (хорошо).

, Поскольку Вы предположили, 1) то, что вызывает нас бесконечная проблема на общих императивных языках и должно было быть запрещено давно, 2) истинная существенная особенность.

существуют языки там, которые избегают 1) не предотвращая 2).

, Например OCaml является таким языком.

А простая функция, возвращая когда-либо увеличивающее целое число, запускающееся от 1:

let counter = ref 0;;
let next_counter_value () = (counter := !counter + 1; !counter);;

И относительно возможностей:

type distributed_computation_result = NotYetAvailable | Result of float;;
let print_result r = match r with
    | Result(f) -> Printf.printf "result is %f\n" f
    | NotYetAvailable -> Printf.printf "result not yet available\n";;
2
ответ дан Peter Mortensen 24 November 2019 в 12:09
поделиться

Существуют ситуации, в которых пустой указатель является хорошим способом показать, что ссылка не была инициализирована. Это важно в некоторых сценариях.

, Например:

MyResource resource;
try
{
  resource = new MyResource();
  //
  // Do some work
  //
}
finally
{
  if (resource != null)
    resource.Close();
}

Это в большинстве случаев выполняется при помощи использование оператор. Но шаблон все еще широко используется.

Относительно Вашего NullReferenceException, причину таких ошибок часто легко уменьшить путем реализации стандарта кодирования где все параметры проверенное для законности. В зависимости от природы проекта я нахожу, что в большинстве случаев достаточно проверить параметры на представленных участниках. Если параметры не в ожидаемом диапазоне , ArgumentException некоторого вида брошен, или ошибочный результат возвращается, в зависимости от используемого шаблона обработки ошибок.

проверка параметра сам по себе не удаляет ошибки, но любых ошибок, которые происходят, легче определить местоположение и исправить во время фазы тестирования.

Как примечание, Anders Hejlsberg упомянул отсутствие непустого осуществления как одна из самых больших ошибок в спецификации C# 1.0 и который включая его теперь является "трудным".

, Если Вы все еще думаете, что статически вынужденное значение ненулевой ссылки очень важно, Вы могли проверить язык spec# . Это - расширение C#, где ненулевые ссылки являются частью языка. Это гарантирует, что ссылке, отмеченной как непустой указатель, никогда нельзя присваивать нулевая ссылка.

3
ответ дан Peter Mortensen 24 November 2019 в 12:09
поделиться

Если Вы получаете 'NullReferenceException', возможно, Вы продолжаете обращаться к объектам, которые больше не существуют. Это не проблема с 'пустым указателем', это - проблема с Вашим кодом, указывающим на несуществующие адреса.

3
ответ дан Glitch 24 November 2019 в 12:09
поделиться

"Пустой указатель" включен в язык, потому что у нас есть типы значения и ссылочные типы. Это - вероятно, побочный эффект, но хороший я думаю. Это дает нам много питания по тому, как мы управляем памятью эффективно.

, Почему у нас есть пустой указатель?...

типы Значения хранятся на "стеке", их значение находится непосредственно в той части памяти (т.е. интервал x = 5 средств это, которое ячейка памяти для той переменной содержит "5").

Ссылочные типы, с другой стороны, имеют "указатель" на стеке, указывающем фактический значение на "куче" (т.е. представьте x в виде строки = "ello", означает, что блок памяти на стеке только содержит адрес, указывающий на фактическое значение на "куче").

нулевое значение А просто означает, что наше значение на стеке не указывает ни на какое фактическое значение на "куче" - это - пустой указатель.

Надежда я объяснил это достаточно хорошо.

3
ответ дан willem 24 November 2019 в 12:09
поделиться

Вопрос может быть интерпретирован, поскольку "Он лучше для имения значения по умолчанию для каждого ссылочного типа (как Строка. Пустой) или пустой указатель?". В этой перспективе я предпочел бы иметь, аннулирует, потому что;

  • я не хотел бы писать конструктора по умолчанию для каждого класса, который я пишу.
  • я не хотел бы, чтобы некоторая ненужная память была выделена для таких значений по умолчанию.
  • Проверка, является ли ссылка пустой, является скорее более дешевой, чем сравнения значения.
  • очень возможно иметь больше ошибок, которые более трудно обнаружить вместо NullReferanceExceptions. Хорошо для имения такого исключения, которое ясно указывает, что я делаю (принятие) чего-то не так.
5
ответ дан tafa 24 November 2019 в 12:09
поделиться

Пустой указатель не вызывает NullPointerExceptions...

Программисты вызывают NullPointerExceptions.

Без пустых указателей мы вернулись к использованию фактического произвольного значения, чтобы решить, что возвращаемое значение функции или метода было недопустимо. Все еще необходимо проверить на возвращенные-1 (или безотносительно), пустые указатели удаления волшебно не решат ленивость, но почти запутают ее.

5
ответ дан Newtopian 24 November 2019 в 12:09
поделиться

, В конце концов, если бы не было никакого "пустого указателя", у меня не было бы ошибки, правильно?

ответ НИКАКОЙ . Проблема не состоит в том, что C# позволяет пустой указатель, проблема состоит в том, что у Вас есть ошибки, которые, оказывается, проявляются с NullReferenceException. Как уже был указан, аннулирует, имеют цель на языке для указания на или "пустой" ссылочный тип или на незначение (empty/nothing/unknown).

12
ответ дан Peter Mortensen 24 November 2019 в 12:09
поделиться

Пустой указатель является чрезвычайно мощной функцией. Что Вы делаете, если у Вас есть отсутствие значения? Это является ПУСТЫМ!

Одна философская школа никогда не должна возвращать пустой указатель, другой к всегда. Например, некоторые говорят, что необходимо возвратить допустимый, но пустой объект.

я предпочитаю пустой указатель относительно меня, это - более истинный признак того, каково это на самом деле. Если я не могу получить объект от своего слоя персистентности, я хочу пустой указатель. Я не хочу некоторое пустое значение. Но это - я.

Это особенно удобно с примитивами. Например, если у меня есть TRUE или FALSE, но он используется на форме безопасности, где разрешение может быть, Позволяют, Отклоняют, или не устанавливают. Ну, я хочу, чтобы это не набор было пустым. Таким образом, я могу использовать bool?

существуют намного больше, я мог продолжить о, но я оставлю его там.

12
ответ дан Peter Mortensen 24 November 2019 в 12:09
поделиться

Удаление пустого указателя не решило бы много. У Вас должна была бы быть ссылка по умолчанию для большинства переменных, которая установлена на init. Вместо исключений нулевой ссылки Вы получили бы неожиданное поведение, потому что переменная указывает на неправильные объекты. По крайней мере, нулевые ссылки перестали работать быстро вместо того, чтобы вызвать неожиданное поведение.

можно посмотреть на шаблон несуществующего объекта для способа решить часть этой проблемы

13
ответ дан Mendelt 24 November 2019 в 12:09
поделиться

Пустой указатель в C# является главным образом переносом от C++, который имел указатели, которые ни на что не указали в памяти (или скорее адресовали 0x00). В [1 111] это интервью , Anders Hejlsberg говорит, что имел бы, любят добавить не допускающие NULL-значения ссылочные типы в C#.

Пустой указатель также имеет законное место в системе типов, однако, как что-то сродни нижний тип (где object вершина тип). В шепелявости нижний тип NIL, и в Scala это Nothing.

было бы возможно разработать C# ни с кем, аннулирует, но тогда необходимо было бы предложить приемлемое решение для использований, которые люди обычно имеют для null, такой как unitialized-value, not-found, default-value, undefined-value, и None<T>. Вероятно, было бы меньше принятия среди C++ и программистов Java, если они действительно преуспевали в этом во всяком случае. По крайней мере, пока они не видели, что программы C# никогда не имели исключений нулевого указателя.

17
ответ дан Mark Cidade 24 November 2019 в 12:09
поделиться

Как много вещей в объектно-ориентированном программировании, все это возвращается к Алголу. Tony Hoare просто назвал это его "ошибкой за миллиард долларов". В любом случае это - преуменьшение.

Вот действительно интересный тезис о том, как сделать nullability не значением по умолчанию в Java. Параллели к C# очевидны.

20
ответ дан Craig Stuntz 24 November 2019 в 12:09
поделиться

Ничтожность является естественным следствием ссылочных типов. Если у Вас есть ссылка, она должна относиться к некоторому объекту - или является пустой. Если бы необходимо было запретить ничтожность, необходимо было бы всегда удостоверяться, что каждая переменная была инициализирована с некоторым ненулевым выражением - и даже тогда у Вас были бы проблемы, если бы переменные были считаны во время фазы инициализации.

, Как Вы предложили бы удалить понятие ничтожности?

29
ответ дан Jon Skeet 24 November 2019 в 12:09
поделиться

Один ответ упомянул, что существуют пустые указатели в базах данных. Это правда, но они очень отличаются от пустых указателей в C#.

В C#, пустые указатели являются маркерами для ссылки, которая ни к чему не относится.

базы данных In, пустые указатели являются маркерами для ячеек значения, которые не содержат значение. Ячейками значения я обычно имею в виду пересечение строки и столбца в таблице, но понятие ячеек значения могло быть расширено вне таблиц.

различие между этими двумя кажется тривиальным, сначала clance. Но это не.

2
ответ дан Walter Mitty 24 November 2019 в 12:09
поделиться