Serkan Kaba

Karalama Defteri

Generics ve Reflection ile genelleştirilmiş dizi yaratma

Posted by Serkan Kaba 29 Nisan 2009

Daha önceden buna benzer bir kodu Java 1.4 ile generics kullanmadan yazmıştım. Ancak Generics’in sağladığı özelliklerle tip dönüşümü kodunu metod içine alarak dışarıya tip güvenli bir metod sunabildim. Şimdi örnek kullanım ile metodumuzu görelim.

import java.lang.reflect.Array;

public class GenericArrayDemo {

	public static void main(String[] args) {
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
	}

	@SuppressWarnings("unchecked")
	public static <T> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				theArray[i]=clazz.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Burada çıktı olarak String[] üretilmekte ve oluşan dizi direk ve yalnız String dizisine atanabilmektedir. Şimdi örneğimizi genişletelim ve metodun sadece Number sınıfının alt sınıflarını üretebilmesini sağlayalım.

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class GenericArrayDemo {

	public static void main(String[] args) {
		/* Bu satırlar artık Number altsınıfı beklediğimizden hata alacaktır.
		System.out.println(getArray(String.class,10).getClass().getSimpleName());
		String theArray[] = getArray(String.class, 10);
		*/
		System.out.println(getArray(Double.class,10).getClass().getSimpleName());
		Long theArray[] = getArray(Long.class, 10);
		for (Long long1 : theArray) {
			System.out.println(long1);
		}
	}

	@SuppressWarnings("unchecked")
	public static <T extends Number> T[] getArray(Class<T> clazz,int size) {
		T theArray[] = (T[])Array.newInstance(clazz, size);
		for(int i=0;i<size;i++)
			try {
				/* 
				 * Number alt sınıfları parametresiz constructor
				 * içermediği için 0 ile ilklendiriyoruz
				 */
				Constructor<T> constructor=clazz.getConstructor(String.class);
				theArray[i]=constructor.newInstance("0");
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		return theArray;
	}
}

Bu metod ise Double[] ve ardından 10 adet sıfır yazdırmaktadır. Artık Number alt sınıfı beklediğinden bir önceki örnekteki satırlar çalışmamaktadır. Burada sınıfa ait String parametresi alan Constructor üretilmekte ve o şekilde ilklenmektedir.

Bunu benim kullanım amacım veritabanında çağırılan stored procedure sonuçlarını uyumlu bir sınıf dizisine eşleyebilen genel bir metod yazmak idi. Belki daha farklı kullanım amaçları da olabilir.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s

 
%d blogcu bunu beğendi: