Java Puzzle 16 – Fence Error

Merhaba Arkadaslar
Ornek kodumuzu incelemeye baslayalim ;

RandomSwitch.java

package _16.fence.error;

import java.util.Random;

public class RandomSwitch {
	private static Random rnd = new Random();

	public static void main(String[] args) {
		StringBuffer word = null;
		switch (rnd.nextInt(2)) {
		case 1:
			word = new StringBuffer('P');
		case 2:
			word = new StringBuffer('G');
		default:
			word = new StringBuffer('M');
		}
		word.append('a');
		word.append('i');
		word.append('n');
		System.out.println(word);
	}
}

Kodumuza ilk olarak baktigimizda ciktimiz Pain, Gain , Main den biri olacak seklinde dusunebiliriz. Ilk harf random uretilen sayiya gore M , P , G olarak secilecek sonrasinda a i n harfleri append edilerek bu kelimelerden biri olacak gibi duruyor.

Ornegimizi calistirdigimizda her zaman ain olarak cikti verecektir.
Peki neden ?

Birinci nokta ;
Random.nextInt(int) metodu ;

Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator’s sequence.

nextInt metodu 0 ile , metoda arguman olarak verilen sayiya kadar olan bir aralikta random olarak bir sayi uretir. Burada metoda verilen deger exclusive/haric birakilir.

Bu nedenle nextInt(2) icin sadece 0 ve 1 sayisi uretilebilir.
O halde hic bir durumda case 2 calismayacaktir. nextInt metoduna 2 degil 3 degerini vermeliyiz.

Bu problem fence post error ile ayni ortak noktadan cikmaktadir.
60 metre uzunlugunda bir bahcemiz olsun , 10 metre arayla cit koymak istersen kactane cit gerekir ?

fence-error

Ornek kodumuzda oldugu gibi nextInt() metodunun exclusive durumuna/sinirina dikkat etmemiz gereklidir!

Bir baska problem olarak switch-case bloklarinda break yok.
Bu durumda uretilen sayi 1 icin yukaridan asagiya dogru sirasiyla

  • case 1
  • case 2
  • default calisir

uretilen sayi 0 icin

  • default calisir.

Oyleyse her sekilde en son olarak su atama/assignment islemi yapilacaktir.

word = new StringBuffer('M');

Peki neden sonuc Main olmuyor ?
Goze carpmayan bug burada StringBuffer(‘M’) dir.
StringBuffer(char) yapilandiricisi yoktur ! char veri tipi int tipiyle uyumludur bu nedenle su overloaed constructor calisacaktir. char veri tipini widening islemine tabi tutulacaktir.

public StringBuffer(int capacity) {
super(capacity);
}

Bu hatadan korunmanin yontemi , kullandigimiz API’leri dogru tanimak metotlari bilmekten gecmektedir.

  • fence post error ‘a karsi dikkatli olalim.
  • switch-case de break’e dikkat edelim. Unutmayalim. Tabi ozellikle koymamamiz gereken bir senaryo da olabilir.
  • char String degildir , fakat int tipine widening islemine tabi tutulabilir.

Bu noktalari dikkate alip bug’lari fixleyelim …

RandomSwitchFixed.java

package _16.fence.error;

import java.util.Random;

public class RandomSwitchFixed {
	private static Random rnd = new Random();

	public static void main(String[] args) {
		StringBuffer word = null;
		switch (rnd.nextInt(3)) {
		case 1:
			word = new StringBuffer("P");
			break;
		case 2:
			word = new StringBuffer("G");
			break;
		default:
			word = new StringBuffer("M");
			break;
		}
		word.append('a');
		word.append('i');
		word.append('n');
		System.out.println(word);
	}
}

Kodu calistirdigimizda uretilen sayiya gore Main , Gain , Pain gibi output verecektir.

Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *