Üçlü Şart Operatörü, “?:”, Muamması

C‘den etkilenen dillerde var olan üçlü operatör (ternary ya da n-ary operator) “?:” bence iki ucu keskin bıçak misali bir operator. Hem son derece kısa ifadeler yazmanıza imkan veriyor hem de anlaşılması zor ifadeler oluşturmanız, örneğin işten ayrılırken kodun içine ufak mayınlar bırakabilmeniz için size fırsat sağlıyor. İşin açıkcası Javacılar bu operatörü çok sık kullanmıyorlar. Hayatında hiç bu operatörü kullanmamış Java programcıları vardır diye eminim.

Önce kısaca bu operatörün yapısından bahsedip sonra sağlıklı kullanımına geleceğim.

“?:” operatörü üç tane operant ya da işlenen/argüman alır. Bunlardan ilki muhakkak boolean/Boolean bir değişken ya da boolean/Boolean üreten bir ifade olmalıdır, aksi taktirde derleme zamanı hatası alınır. Bir başka deyişle bu operatör, “if-else”in ya da “or” mantıksal işleminin kısaltılmış halidir. İlk ifade doğru ise ikinci ifade, değil ise üçüncü ifade, atamanın solundaki değere atanır.

...
int ilki = 8;

int ikincisi = 11;

int min = (ilki <= ikincisi) ? ilki : ikincisi;

System.out.println(min);
...

Yukarıdaki ifadede int olan min değişkenine “ilki <= ikincisi” ifadesinin değerine göre ya ilki ya da ikincisi ile ilk değer ataması yapılacaktır. Dolayısıyla min değişkenine “8” atanacaktır.

Daha açık  bir örnek şu olabilir:

...
System.out.println(true ? "true" : "false" );
System.out.println(false ? "true" : "false" );
...

Burada dikkat edilmesi gereken şeylerden birisi de ikinci ve üçüncü ifadelerin void dondüren bir metot olmaması gerektiğidir.

...
String string1 = "I love Java very much.";
String string2 = (string1.matches(".*Java.*")) ?
                  string1 : "I love nothing.";
System.out.println(string2);
...

Bu örnekler üçlü şart operatörünün güzel kullanımlarındandır. Bu şekilde böyle daha uzun kod yazmaktan kurtulmuş oluyoruz:

...
String string1 = "I love Java.";
if(string1.matches(".*Java.*"))
   string2 = string1;
else
   string2 = "I love nothing.";
System.out.println(string2);
...

Bu operatörün iki ucu keskin olduğunu söylemiştim. Bakın şuna:

...
student.setId(student.getTcCitizen() ?
 (StrUtils.checkNullOrEmpty(studentService.getCurrentStudent().getTckn()) ?
  model.getTckn():studentService.getCurrentStudent().getTckn())
  :(StrUtils.checkNullOrEmpty(studentService.getCurrentStudent.getId()))  ?
  model.getId(): studentService.getCurrentStudent().getId());
...

Buyrun cenaze namazına di mi?

Bu kodda “?:” operatörü son derece yanlış bir şekilde kullanılmıştır. Yukarıdaki kod parçasının daha açık hallerinden birisi şöyle olabilir:

...
 // Burada Student’ın Idsi atanır. Id olarak eğer öğrenci TC
 // vatandasi ise ya servisten ya da modelden gelen tckn atanır.
 // Eğer öğrenci TC vatandasi değilse Id olarak student id
 // alınır. Burada da yine ya servisten ya da modelden gelen
 // student id atanır.

 String no = null;
 boolean isTcCitizen = student.getTcCitizen();
 String tcknFromModel = model.getTckn();
 String tcknFromService = studentService.getCurrentStudent().getTckn();
 boolean nullOrEmptyTcknFromService = StrUtils.isNullOrEmpty(tcknFromService);
 String studentIdFromService = studentService.getCurrentStudent().getId();
 boolean nullOrEmptyIdFromService = formUtils.isNullOrEmpty(studentIdFromService);

if(isTcCitizen){
   if(nullOrEmptyTcknFromService)
      no = tcknFromModel;
   else
      no = tcknFromService;

else{
   if(nullOrEmptyIdFromService)
      no = tcknFromModel;
   else
      no = studentIdFromService
}
student.setId(no);
...

İşin açıkçası yukarıdaki kodda işlenen tek günah “?:” operatörü ile ilgili değil. Bir arada bir sürü isimlendirme ve etkin kodlama hatası var. Ama en büyüğü sanırım bu operatörün kullanımında.

Allah tüm Javacıları böyle kodlar devralmak ve yazmaktan korusun 🙂

Bu yazı toplam 1509 defa görüntülenmiştir.