Оператор ==
проверяет, указывают ли две ссылки на один и тот же объект или нет. .equals()
проверьте фактическое содержимое строки (значение).
Обратите внимание, что метод .equals()
принадлежит классу Object
(суперкласс всех классов). Вам необходимо переопределить его в соответствии с вашим требованием к классу, но для String оно уже реализовано и проверяет, имеет ли две строки одно и то же значение.
String s1 = "Stack Overflow";
String s2 = "Stack Overflow";
s1 == s2; //true
s1.equals(s2); //true
Причина: строка литералы, созданные без нуля, хранятся в пуле строк в области перментонов кучи. Таким образом, оба s1 и s2 указывают на один и тот же объект в пуле. String s1 = new String("Stack Overflow");
String s2 = new String("Stack Overflow");
s1 == s2; //false
s1.equals(s2); //true
Причина. Если вы создаете объект String с использованием ключевого слова new
, ему выделяется отдельное пространство в куче. .o
Файлы и исполняемый файл ($(OUTPUT)
) являются отдельными правилами. Если последнее не удается, первое уже не рассматривается. См. Документацию :
blockquote>
.DELETE_ON_ERROR:
Если.DELETE_ON_ERROR
упоминается как цель где-либо в make-файле, тоmake
удалит цель правила, если оно изменилось и его рецепт завершается с ненулевым статусом выхода, так же, как и при получении сигнала. См. Ошибки в рецептах .Другими словами, если ваша цель, создающая бинарный объект, потерпела неудачу после того, как сама цель
.o
была обновлена, make уничтожит измененный файл. Но если ваш исполняемый файл не связывался, он не вернется и не удалит объектные файлы.Не уверен, что это было бы неплохо, но если бы вам действительно это было нужно, вы, вероятно, могли бы добиться этого путем рефакторинга вашего make-файла, чтобы в основном иметь прямое exec + objs из правила исходных условий с одним рецептом. Очевидный недостаток: такое правило будет означать изменение одного файла
.c
, в результате чего все файлы будут перекомпилированы (в основном сводит на нет существенные преимущества использованияmake
).
РЕДАКТИРОВАТЬ: Я немного расширю комментарий, чтобы прояснить. Похоже, что вам нужно: в случае, если файл
.c
поврежден и сборка не удалась, удалите старый файл.o
. Это совершенно не совсем так, как работает.DELETE_ON_ERROR
. Если файл.o
уже обновлен, а затем правило не выполнено, он удаляет его ( «удаляет цель правила, если оно изменилось» ), но в случае упомянутой синтаксической проблемы, компилятор потерпит неудачу, прежде чем он создаст файл.o
.Итак, если, например, вы обновили свое правило (шаблон) для компиляции, чтобы оно сначала
touch
присваивало (эффективно обновляет метку времени) файл.o
, а затем пытается компилировать. После сбоя вызова компилятора и правила make сочтет, что цель поврежденного корня была обновлена, и удалит ее. В качестве альтернативы вы также можете изменить правило, чтобы сначала попытатьсяrm
получить ожидаемый файл «.o», и в этом случае вам на самом деле не нужно будет использовать.DELETE_ON_ERROR
(и если нет изменений в соответствующих источниках, правило делает не привыкать, так что на самом деле это не так страшно, как кажется). В любом случае это не совсем чисто, но ведет к поведению, которое, как я понимаю, вы описываете.