Java'da iddialar nasıl kullanılır

Çalışma zamanında doğru şekilde çalışan programlar yazmak zor olabilir. Bunun nedeni, kodumuzun çalıştırıldığında nasıl davranacağına ilişkin varsayımlarımızın çoğu zaman yanlış olmasıdır. Java'nın onaylama özelliğini kullanmak, programlama mantığınızın sağlam olduğunu doğrulamanın bir yoludur.

Bu eğitim, Java iddialarını tanıtır. İlk önce hangi iddiaların olduğunu ve bunları nasıl belirtip kodunuzda kullanacağınızı öğreneceksiniz. Daha sonra, ön koşulları ve son koşulları uygulamak için iddiaları nasıl kullanacağınızı keşfedeceksiniz. Son olarak, iddiaları istisnalarla karşılaştıracak ve kodunuzda neden her ikisine de ihtiyacınız olduğunu öğreneceksiniz.

indir Kodu alın Bu eğitimdeki örnekler için kaynak kodunu indirin. JavaWorld için Jeff Friesen tarafından düzenlendi.

Java iddiaları nelerdir?

JDK 1.4'ten önce, geliştiriciler programın doğruluğu hakkındaki varsayımları belgelemek için sık sık yorumları kullanırlardı. Ancak yorumlar, varsayımları test etmek ve hata ayıklamak için bir mekanizma olarak işe yaramaz. Derleyici yorumları yok sayar, bu yüzden onları hata tespiti için kullanmanın bir yolu yoktur. Geliştiriciler ayrıca kodu değiştirirken yorumları sık sık güncellemez.  

JDK 1.4'te, kodumuzla ilgili varsayımları test etmek ve hata ayıklamak için yeni bir mekanizma olarak iddialar tanıtıldı. Özünde, iddialar  , program testi için onları etkinleştirdiğiniz varsayılarak, çalışma zamanında çalıştırılan derlenebilir varlıklardır. Hataların meydana geldiği yerdeki hataları size bildirmek için iddiaları programlayabilirsiniz, aksi takdirde başarısız bir programda hata ayıklamak için harcayacağınız zamanı büyük ölçüde azaltabilirsiniz.

İddialar, doğru değerler için koşulları (Boole ifadeleri) test ederek ve bu tür koşullar yanlış olduğunda geliştiriciyi bilgilendirerek bir programı doğru ya da değil oluşturan gereksinimleri kodlamak için kullanılır . İddiaları kullanmak, kodunuzun doğruluğuna olan güveninizi büyük ölçüde artırabilir.

Java'da bir iddia nasıl yazılır

İddialar, assertifade ve java.lang.AssertionErrorsınıf aracılığıyla gerçekleştirilir . Bu ifade anahtar sözcükle başlar assertve bir Boole ifadesi ile devam eder. Sözdizimsel olarak şu şekilde ifade edilir:

BooleanExpr iddia edin ;

Doğru olarak BooleanExprdeğerlendirilirse hiçbir şey olmaz ve yürütme devam eder. Bununla birlikte, ifade yanlış olarak değerlendirilirse AssertionError, Liste 1'de gösterildiği gibi somutlaştırılır ve atılır.

Liste 1:AssertDemo.java (sürüm 1)

public class AssertDemo {public static void main (String [] değiştirgeler) {int x = -1; x> = 0 olduğunu varsayalım; }}

Liste 1'deki iddia, geliştiricinin değişkenin x0'dan büyük veya 0'a eşit bir değer içerdiğine olan inancını gösterir. Ancak, durum açıkça bu değildir; assertBir de ifadenin çalıştırılması sonucu atılan AssertionError.

Liste 1'i ( javac AssertDemo.java) derleyin ve onaylar etkinken çalıştırın ( java -ea AssertDemo). Aşağıdaki çıktıyı gözlemlemelisiniz:

AssertDemo.main konumunda "main" java.lang.AssertionError iş parçacığında istisna (AssertDemo.java:6)

Bu mesaj, AssertionErroratılmasına neyin sebep olduğunu tanımlamaması açısından biraz şifreli . Daha bilgilendirici bir mesaj istiyorsanız, assertaşağıda ifade edilen ifadeyi kullanın :

BooleanExpr iddia : ifade ;

Burada, exprbir değer döndürebilen herhangi bir ifade (yöntem çağrısı dahil) gösterilmektedir - voiddönüş türü olan bir yöntemi çağıramazsınız . Kullanışlı bir ifade, Liste 2'de gösterildiği gibi, başarısızlığın nedenini açıklayan bir dizedir.

Liste 2:AssertDemo.java (sürüm 2)

public class AssertDemo {public static void main (String [] değiştirgeler) {int x = -1; x> = 0: "x <0"; }}

Liste 2'yi ( javac AssertDemo.java) derleyin ve onaylar etkinken çalıştırın ( java -ea AssertDemo). Bu sefer, fırlatılma nedenini içeren aşağıdaki biraz genişletilmiş çıktıyı gözlemlemelisiniz AssertionError:

"Main" iş parçacığında istisna java.lang.AssertionError: AssertDemo.main'de x <0 (AssertDemo.java:6)

Her iki örnekte de, (isimleri etkinleştir) seçeneği AssertDemoolmadan çalıştırmak -eaçıktı vermez. İddialar etkinleştirilmediğinde, sınıf dosyasında hala mevcut olsalar bile yürütülmezler.

Ön koşullar ve son koşullar

İddialar, çeşitli ön koşullarının ve son koşullarının ihlal edilmediğini doğrulayarak bir programın varsayımlarını test eder ve bir ihlal meydana geldiğinde geliştiriciyi uyarır:

  • Ön koşul , bazı kod dizilerinin yürütülmesinden önce doğru olarak değerlendirilmesi gereken bir koşuldur . Ön koşullar, arayanların callees ile sözleşmelerini korumasını sağlar.
  • Son koşul , bazı kod dizilerinin yürütülmesinden sonra doğru olarak değerlendirilmesi gereken bir koşuldur. Son koşullar, arayanların arayanlarla olan sözleşmelerini korumasını sağlar.

Ön koşullar

Gerektiğinde açık denetimler yaparak ve istisnalar atarak genel oluşturucular ve yöntemler üzerinde ön koşulları uygulayabilirsiniz. Özel yardımcı yöntemler için, iddiaları belirterek ön koşulları uygulayabilirsiniz. Liste 3'ü düşünün.

Liste 3:AssertDemo.java (sürüm 3)

java.io.FileInputStream'i içe aktarın; java.io.InputStream'i içe aktarın; java.io.IOException'ı içe aktarın; sınıf PNG {/ ** * Bir PNG örneği oluşturun, belirtilen PNG dosyasını okuyun ve kodunu * uygun yapılara dönüştürün. * * @param filepec yolu ve okunacak PNG dosyasının adı * * @ NullPointerException olduğunda filespec*null* / PNG (Dize dosya belirtimi) IOException oluşturur {// Özel olmayan oluşturucularda ve // ​​yöntemlerde ön koşulları uygular. if (filespec == null) yeni NullPointerException ("dosya belirtimi boştur") atar; deneyin (FileInputStream fis = new FileInputStream (filespec)) {readHeader (fis); }} private void readHeader (InputStream is) IOException atar {// Özel // yardımcı yöntemlerde ön koşulun sağlandığını onaylayın. assert! = null: "null geçildi"; }} public class AssertDemo {public static void main (String [] args), IOException {PNG png = new PNG ((args.length == 0)? null: args [0]); }}

PNGListesinde 3 sınıf okuma ve PNG (taşınabilir ağ grafikleri) görüntü dosyaları deşifre edilmesi için bir kütüphaneye minimal bir başlangıçtır. Yapıcı açıkça karşılaştırır filespecile nullatma, NullPointerExceptionbu parametre içerdiğinde null. Önemli olan, filespeciçermeyen ön koşulu uygulamaktır null.

assert filespec != null;Yapıcının Javadoc'unda belirtilen ön koşul, iddialar devre dışı bırakıldığında (teknik olarak) yerine getirilmeyeceği için belirtmek uygun değildir. (Aslında onurlandırılır çünkü FileInputStream()fırlatırdı NullPointerException, ancak belgelenmemiş davranışlara güvenmemelisin.)

Ancak, bir PNG dosyasının 8 baytlık başlığını okumak ve kodunu çözmek için sonunda tamamlanacak olan assertözel readHeader()yardımcı yöntem bağlamında uygundur . Her iszaman boş olmayan bir değer geçirilen ön koşul her zaman geçerli olacaktır.

Son koşullar

Son koşullar, yöntemin (veya yapıcının) herkese açık olup olmadığına bakılmaksızın, genellikle iddialar aracılığıyla belirlenir. Liste 4'ü düşünün.

Liste 4:AssertDemo.java (sürüm 4)

public class AssertDemo { public static void main(String[] args) { int[] array = { 20, 91, -6, 16, 0, 7, 51, 42, 3, 1 }; sort(array); for (int element: array) System.out.printf("%d ", element); System.out.println(); } private static boolean isSorted(int[] x) { for (int i = 0; i  x[i + 1]) return false; return true; } private static void sort(int[] x) { int j, a; // For all integer values except the leftmost value ... for (int i = 1; i  0 && x[j - 1] > a) { // Shift left value -- x[j - 1] -- one position to its right -- // x[j]. x[j] = x[j - 1]; // Update insert position to shifted value's original position // (one position to the left). j--; } // Insert a at insert position (which is either the initial insert // position or the final insert position), where a is greater than // or equal to all values to its left. x[j] = a; } assert isSorted(x): "array not sorted"; } }

Listing 4 presents a sort() helper method that uses the insertion sort algorithm to sort an array of integer values. I’ve used assert to check the postcondition of x being sorted before sort() returns to its caller.

The example in Listing 4 demonstrates an important characteristic of assertions, which is that they’re typically expensive to execute. For this reason, assertions are usually disabled in production code. In Listing 4, isSorted() must scan through the entire array, which can be time-consuming in the case of a lengthy array.

Assertions vs. exceptions in Java

Developers use assertions to document logically impossible situations and detect errors in their programming logic. At runtime, an enabled assertion alerts a developer to a logic error. The developer refactors the source code to fix the logic error and then recompiles this code.

Developers use Java’s exception mechanism to respond to non-fatal (e.g., running out of memory) runtime errors, which may be caused by environmental factors, such as a file not existing, or by poorly written code, such as an attempt to divide by 0. An exception handler is often written to gracefully recover from the error so that the program can continue to run.

Assertions are no substitute for exceptions. Unlike exceptions, assertions don’t support error recovery (assertions typically halt program execution immediately — AssertionError isn’t meant to be caught); they are often disabled in production code; and they typically don’t display user-friendly error messages (although this isn’t an issue with assert). It’s important to know when to use exceptions rather than assertions.

When to use exceptions

Suppose you’ve written a sqrt() method that calculates the square root of its argument. In a non-complex number context, it’s impossible to take the square root of a negative number. Therefore, you use an assertion to fail the method if the argument is negative. Consider the following code fragment:

public double sqrt(double x) { assert x >= 0 : "x is negative"; // ... }

It’s inappropriate to use an assertion to validate an argument in this public method. An assertion is intended to detect errors in programming logic and not to safeguard a method from erroneous arguments. Besides, if assertions are disabled, there is no way to deal with the problem of a negative argument. It’s better to throw an exception, as follows:

public double sqrt(double x) { if (x < 0) throw new IllegalArgumentException("x is negative"); // ... }

The developer might choose to have the program handle the illegal argument exception, or simply propagate it out of the program where an error message is displayed by the tool that runs the program. Upon reading the error message, the developer can fix whatever code led to the exception.

İddia ve hata tespit mantığı arasında ince bir fark olduğunu fark etmiş olabilirsiniz. İddia testleri x >= 0, hata bulma mantığı ise test eder x < 0. İddia iyimserdir: Argümanın tamam olduğunu varsayıyoruz. Aksine, hata saptama mantığı kötümserdir: Argümanın tamam olmadığını varsayıyoruz. Onaylar doğru mantığı belgelerken, istisnalar yanlış çalışma zamanı davranışını belgeler.

Bu eğitimde, doğru program mantığını belgelemek için iddiaları nasıl kullanacağınızı öğrendiniz. Ayrıca iddiaların neden istisnaların yerini tutmadığını da öğrendiniz ve istisna kullanmanın daha etkili olacağı bir örnek gördünüz.

"Java'da iddialar nasıl kullanılır" başlıklı bu hikaye, orijinal olarak JavaWorld tarafından yayınlanmıştır.