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, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
C#: Слева направо и обработка остановок, если несоответствие (оценивает ко лжи) найдено.
Вы используете & когда Вы конкретно хотите оценить все подвыражения, скорее всего, потому что у них есть побочные эффекты, Вы хотите, даже при том, что конечный результат будет ложь и таким образом не выполнит Ваш затем часть Вашего если - оператор.
Примечание это & и | работает и для поразрядных масок и для булевых значений и не только для битовых операций. Они названы поразрядный, но они определяются и для целых чисел и для булевых типов данных в C#.
Я услышал где-нибудь, что компиляторы работают назад, но я не уверен, насколько верный это.
попросили в продолжении, почему или когда будет любой использовать И вместо AndAlso (или & вместо & &): Вот пример:
if ( x.init() And y.init()) then x.process(y) end y.doDance()
В этом случае, я хочу к init обоих X и Y. Y должен быть инициализирован для y. DoDance, чтобы смочь выполниться. Однако в init () функционируют, я делаю также некоторую дополнительную вещь как проверка, что сокет открыт, и только если это удается хорошо для обоих, я должен идти вперед и сделать x.process (y).
я полагаю, что это довольно сбивает с толку. Хотя Ваш пример работает, это не типичный случай для использования And
(и я, вероятно, записал бы это по-другому для создания этого более ясным). And
(&
на большинстве других языков) на самом деле поразрядное - и операция. Вы использовали бы его для вычисления битовых операций, например, удаляя флаговый бит или маскируя и тестируя флаги:
Dim x As Formatting = Formatting.Bold Or Formatting.Italic
If (x And Formatting.Italic) = Formatting.Italic Then
MsgBox("The text will be set in italic.")
End If
, Что такое хороший пример того, когда использовать побитовый оператор вместо "закороченной булевской переменной"?
предположим Вы имеете флаги, говорите для атрибутов файла. Предположим, что Вы определили ЧТЕНИЕ как 4, ЗАПИШИТЕ как 2, и ДОЛЖНОСТНОЕ ЛИЦО как 1. В двоичном файле это:
READ 0100
WRITE 0010
EXEC 0001
Каждый флаг имеет один набор битов, и каждый уникален. Побитовые операторы позволяют Вам объединить эти флаги:
flags = READ & EXEC; // value of flags is 0101
Скромность понятия относится к, перегрузка оператора. в операторе:
if( A && B){
// do something
}
А оценен сначала, если он оценивает ко лжи, B никогда не оценивается. То же относится
if(A || B){
//do something
}
, А оценен сначала, если это оценивает к истинному, B никогда не оценивается.
Это понятие, перегрузка, относится (я думаю), все языки стиля C и многие другие также.
Когда вещи все встроены, они выполняются слева направо.
, Когда вещи вкладываются, они выполняются внутренние-к-внешнему. Это может казаться сбивающим с толку как обычно, что "само внутреннее", имеет на правой стороне строку, таким образом, кажется, что это идет назад...
, Например
a = Foo( 5, GetSummary( "Orion", GetAddress("Orion") ) );
Вещи происходят как это:
GetAddress
с литералом "Orion"
GetSummary
с литералом "Orion"
и результат GetAddress
Foo
с литералом 5
и результат GetSummary
a
Мне нравятся ответы Orion. Я добавлю две вещи:
Говорят, что у нас есть следующий пример:
a = Foo(5, GetSummary("Orion", GetAddress("Orion")),
GetSummary("Chris", GetAddress("Chris")));
Вот порядок выполнения:
GetAddress("Orion")
GetSummary("Orion", ...)
GetAddress("Chris")
GetSummary("Chris", ...)
Foo(...)
a
, я не могу говорить о законных требованиях C# (хотя я действительно тестировал подобный пример, использующий Моно прежде, чем записать это сообщение), но этот порядок гарантируется в Java.
И только для полноты (так как это - агностический языком поток также), существуют языки как C и C++, где порядок не гарантируется, если не будет точка последовательности. Ссылки: 1 , 2 . В ответе на вопрос потока, однако, &&
и ||
точки последовательности в C++ (если не перегружено; также см. превосходный ответ OJ). Так некоторые примеры:
foo() && bar()
foo() & bar()
В &&
случай, foo()
, как гарантируют, будет работать прежде bar()
(если последний будет выполнен вообще), так как &&
точка последовательности. В &
случай, никакая такая гарантия не сделана (в C и C++), и действительно bar()
может работать прежде foo()
, или наоборот.
Nopes, по крайней мере, компилятор C# не работает назад (в любом & & или ||). Это слева направо.
Некоторые языки имеют интересные ситуации, где выражения выполняются в другом порядке. Я конкретно думаю о Ruby, но я уверен, что они одолжили его откуда-либо (вероятно, Perl).
выражения в логике останутся слева направо, но например:
puts message unless message.nil?
Вышеупомянутое оценит "message.nil?" сначала, затем если это оценивает ко лжи (если не похож, если кроме него выполняется, когда условие является ложью вместо истинного), "помещает сообщение", выполнится, который печатает содержание переменной сообщения на экран.
Это - вид интересного способа иногда структурировать Ваш код... Мне лично нравится использовать его для очень короткого 1 лайнера как вышеупомянутое.
Редактирование:
Для создания этого немного более ясным вышеупомянутое совпадает с:
unless message.nil?
puts message
end
ZombieSheep мертв - на. Единственный "глюк", который мог бы ожидать, - то, что это только верно при использовании & & оператор. При использовании & оператор, оба выражения будут оценены каждый раз, независимо если один или оба оценят ко лжи.
if (amHungry & whiteCastleIsNearby)
{
// The code will check if White Castle is nearby
// even when I am not hungry
}
if (amHungry && whiteCastleIsNearby)
{
// The code will only check if White Castle is nearby
// when I am hungry
}
Я понимаю, что на этот вопрос уже ответили, но я хотел бы добавить другой бит информации, которая связана с темой.
На языках, как C++, где можно на самом деле перегрузить поведение & & и || операторы, настоятельно рекомендовано, что Вы не делаете этого . Это вызвано тем, что при перегрузке этого поведения Вы заканчиваете тем, что вызвали оценку обеих сторон операции. Это делает две вещи:
Для большего количества информации, имейте чтение книги Scott Meyers, Более эффективный C++ .Удачи!
Обратите внимание, что существует различие между & & и & относительно того, сколько из Вашего выражения оценен.
& & известен как закороченная булевская переменная И, и, как отмечено другими здесь, остановится рано, если результат может быть определен, прежде чем все подвыражения будут оценены.
& известен как логический побитовый оператор и будет всегда оценивать все подвыражения.
Как таковой:
if (a() && b())
будет только звонить b если возвраты верный .
однако, это:
if (a() & b())
будет всегда звонить и и b, даже при том, что результатом вызова является ложь и таким образом известный быть ложь независимо от результата вызова b.
Это то же различие существует для || и | операторы.
@shsteimer
, к которому относится скромность понятия, является перегрузкой оператора. в операторе:... A оценен сначала, если он оценивает ко лжи, B никогда не оценивается. То же относится
, Это не перегрузка оператора. Перегрузка оператора является термином, данным для разрешения Вам определить пользовательское поведение для операторов, такой как *, +, = и так далее.
Это позволило бы Вам записать свой собственный класс 'Журнала' и затем сделать
a = new Log(); // Log class overloads the + operator
a + "some string"; // Call the overloaded method - otherwise this wouldn't work because you can't normally add strings to objects.
Выполнение, это
a() || b() // be never runs if a is true
на самом деле называют Оценка Короткого замыкания
vb.net
if( x isNot Nothing AndAlso x.go()) then
, можно использовать И вместо этого ofAndAlso в vb., в этом случае, левая сторона оценена сначала также, но правая сторона будет оценена независимо от результата.
Лучшая практика: Всегда используйте AndAlso, если у Вас нет очень серьезного основания почему не к.
<час>попросили в продолжении, почему или когда будет любой использовать И вместо AndAlso (или & вместо & &): Вот пример:
if ( x.init() And y.init()) then
x.process(y)
end
y.doDance()
В этом случае, я хочу к init обоих X и Y. Y должен быть инициализирован для y. DoDance, чтобы смочь выполниться. Однако в init () функционируют, я делаю также некоторую дополнительную вещь как проверка, что сокет открыт, и только если это удается хорошо, для [1 116] и , я должен идти вперед и сделать x.process (y).
Снова, это, вероятно, не нужно и не изящно в 99% случаев, именно поэтому я сказал, что значение по умолчанию должно быть должно использовать AndAlso.
"C#: Слева направо и обработка остановок, если соответствие (оценивает к истинному) найдено".
овца Зомби неправа, недостаточно представителя, чтобы вниз проголосовать за него.
вопрос о & & оператор, не || оператор.
В случае & & оценка остановится, если ЛОЖЬ будет найдена.
В случае || оценка останавливается, если TRUE найден.
Левые один, затем останавливается, если это является пустым.
Редактирование: В vb.net это оценит обоих и возможно бросит ошибку, если Вы не будете использовать AndAlso
Язык программирования D выполняет оценку слева направо с коротким замыканием , а не допускает перегрузку &&
и '||' операторы.