os operadores != == quando usados com objetos (ou suas variáveis de referência) verificam se são o mesmo objeto contida na heap (área da memoria criada pela JVM onde os objetos residem)
Contudo a String retornada por sc.nextLine() é diferente da String “0”. sim, eles possuem o mesmo valor mas ainda são dois objetos separados que por um acaso carregam o mesmo valor (quando o usuário digitar zero).
“Ta e como eu resolvo esse problema?”
while(true) {
String opcao = sc.nextLine();
//o método equals verifica se dois objetos possuem o mesmo valor
//existe também o método equalsIgnoreCase() que ignora maiusculas e minusculas
if(opcao.equals("0")) {
break;
}
else{
System.out.println("oi");
}
}