Java использует «строковый литерал». Поскольку строки являются неизменяемыми объектами, нет причин, по которым две строки, инициализированные одним и тем же литералом, не могут быть одним и тем же объектом - и, как показывает вывод вашего кода, они являются одним и тем же объектом. (s1 и s2 - два имени для одного и того же места в памяти)
Причина, по которой это не так для s3 и s4, заключается в том, что вы явно выделяете новые строки и используете конструктор для их инициализации. Это означает, что они являются различными объектами, и, следовательно, они не проходят тест "==".
Другими словами,
== сравнивает, если две ссылки на объекты равны
.equals () сравнивает, если содержимое двух объектов равно, независимо от того, где они находятся в памяти.