java reflection tutorial with examples
Bu Video Eğitimi, Reflection'ın ne olduğunu ve Reflection API'yi kullanarak nasıl Uygulanacağını açıklar:
Java'daki yansıma, bir programın davranışını çalışma zamanında incelemek ve değiştirmektir.
Bu yansıma API'sinin yardımıyla, çalışma zamanında sınıfları, yapıcıları, değiştiricileri, alanları, yöntemleri ve arabirimleri inceleyebilirsiniz. Örneğin, sınıfın adını alabilir veya sınıfın özel üyelerinin detaylarını alabilirsiniz.
Baştan sona okuyun JAVA eğitim serisi Java kavramları hakkında daha fazla bilgi için.
İşte Java Yansıması üzerine bir Video Eğitimi:
Ne öğreneceksin:
Java'da Yansıma
Belirli bir sınıfta özelliklerini ve yöntemlerini derleme zamanında değiştirebileceğimizi ve bunu yapmanın çok kolay olduğunu biliyoruz. Özellikler ve yöntemler anonim veya isme sahip olsun, derleme sırasında isteğimiz doğrultusunda değiştirilebilirler.
Ancak bu sınıfları veya yöntemleri veya alanları çalışma zamanında anında değiştiremeyiz. Başka bir deyişle, özellikle bilinmeyen nesneler için çalışma zamanında çeşitli programlama bileşenlerinin davranışını değiştirmek çok zordur.
Java programlama dili, 'Yansıma' bu, çalışma zamanında bir sınıfın veya alanın veya yöntemin çalışma zamanı davranışını değiştirmemize olanak tanır.
Böylelikle bir Yansıma, bir 'Bilinmeyen bir nesnenin çalışma zamanı davranışını çalışma zamanında inceleme ve değiştirme tekniği. Bir nesne bir sınıf, alan veya yöntem olabilir. '
Yansıma, Java tarafından sağlanan bir 'Uygulama Programlama Arayüzü' dür (API).
'Yansıma' süreci aşağıda tasvir edilmiştir.
Yukarıdaki gösterimde bilinmeyen bir nesneye sahip olduğumuzu görebiliriz. Daha sonra bu nesne üzerinde Reflection API'yi kullanıyoruz. Sonuç olarak, bu nesnenin davranışını çalışma zamanında değiştirebiliriz.
Böylece, nesnenin davranışını değiştirmek amacıyla programlarımızda Reflection API kullanabiliriz. Nesneler, yöntemler, arayüzler, sınıflar vb. Gibi herhangi bir şey olabilir. Bu nesneleri inceliyoruz ve ardından yansıma API'sini kullanarak çalışma zamanında davranışlarını değiştiriyoruz.
Java'da, 'java.lang' ve 'java.lang.reflect', yansıtma için sınıflar sağlayan iki pakettir. Özel 'java.lang.Class' sınıfı, sınıf davranışını inceleyip değiştirebileceğimiz meta verileri çıkarmak için yöntemler ve özellikler sağlar.
Çalışma zamanında alanlar, yöntemler, yapıcılar vb. Dahil olmak üzere sınıfı ve üyelerini değiştirmek için yukarıdaki paketler tarafından sağlanan Reflection API'yi kullanıyoruz. Reflection API'nin ayırt edici bir özelliği, sınıfın özel veri üyelerini veya yöntemlerini de değiştirebilmemizdir.
Reflection API esas olarak şu alanlarda kullanılır:
- Yansıma, çalışma zamanında davranışı incelemek ve değiştirmek için temel olarak hata ayıklama araçlarında, JUnit'te ve çerçevelerde kullanılır.
- IDE (Entegre Geliştirme Ortamı) Örneğin. Eclipse IDE, NetBeans vb.
- Test Araçları vb.
- Uygulamanızda üçüncü taraf kitaplıklar olduğunda ve mevcut sınıflar ve yöntemler hakkında bilgi almak istediğinizde kullanılır.
Java'da Reflection API
Reflection API'yi kullanarak yansımayı aşağıdaki varlıklara uygulayabiliriz:
- Alan : Field sınıfı, bir değişken veya veri türü (int, double, String, vb.), Erişim değiştirici (özel, genel, korumalı vb.), Ad (tanımlayıcı) ve değer gibi bir alanı bildirmek için kullandığımız bilgilere sahiptir.
- Yöntem : Method sınıfı, yöntemin erişim değiştiricisi, yöntem dönüş türü, yöntem adı, yöntem parametre türleri ve yöntem tarafından oluşturulan istisna türleri gibi bilgileri ayıklamamıza yardımcı olabilir.
- Oluşturucu : Yapıcı sınıfı, yapıcı erişim değiştiricisi, yapıcı adı ve parametre türlerini içeren sınıf yapıcısı hakkında bilgi verir.
- Düzenle : Değiştirici sınıfı bize belirli bir erişim değiştirici hakkında bilgi verir.
Yukarıdaki tüm sınıflar java.lang.reflect paketinin bir parçasıdır. Daha sonra, bu sınıfların her birini tartışacağız ve bu sınıflar üzerindeki yansımayı göstermek için programlama örneklerini kullanacağız.
İlk olarak java.lang.Class sınıfıyla başlayalım.
java.lang.Class Sınıfı
Java.lang.The sınıfı, çalışma zamanında sınıflar ve nesneler hakkındaki tüm bilgileri ve verileri tutar. Bu, yansıtma için kullanılan ana sınıftır.
Java.lang.Class sınıfı şunları sağlar:
- Çalışma zamanında sınıf meta verilerini alma yöntemleri.
- Çalışma zamanında bir sınıfın davranışını inceleme ve değiştirme yöntemleri.
Java.lang.Class Nesneleri Oluşturun
Aşağıdaki seçeneklerden birini kullanarak java.lang.Class nesnelerini oluşturabiliriz.
c ++ 'da basit birleştirme sıralama programı
# 1) .class uzantısı
Class nesnesini oluşturmanın ilk seçeneği .class uzantısını kullanmaktır.
Örneğin,Test bir sınıfsa, aşağıdaki gibi bir Class nesnesi oluşturabiliriz:
Class obj_test = Test.class;
Daha sonra yansıma yapmak için obj_test'i kullanabiliriz çünkü bu nesne Test sınıfı ile ilgili tüm bilgilere sahip olacaktır.
# 2) forName () yöntemi
forName () yöntemi, sınıfın adını bağımsız değişken olarak alır ve Class nesnesini döndürür.
Örneğin,Test sınıfının nesnesi şu şekilde oluşturulabilir:
class obj_test = Class.forName (“Test”);
# 3) getClas () yöntemi
getClass () yöntemi, java.lang.Class nesnesini almak için bir sınıfın nesnesini kullanır.
Örneğin,aşağıdaki kod parçasını düşünün:
Test obj = new Test (); Class obj_test = obj.getClass ();
İlk satırda Test sınıfının bir nesnesini oluşturduk. Daha sonra bu nesneyi kullanarak java.lang.Class'ın obj_test nesnesini elde etmek için “getClass ()” yöntemini çağırdık.
Süper Sınıf ve Erişim Değiştiricileri Edinin
java.lang.class, herhangi bir sınıfın üst sınıfını almak için kullanılan bir 'getSuperClass ()' yöntemi sağlar.
Benzer şekilde, sınıfın erişim değiştiricisini döndüren getModifier () yöntemini sağlar.
Aşağıdaki örnek getSuperClass () yöntemini gösterir.
import java.lang.Class; import java.lang.reflect.*; //define Person interface interface Person { public void display(); } //declare class Student that implements Person class Student implements Person { //define interface method display public void display() { System.out.println('I am a Student'); } } class Main { public static void main(String() args) { try { // create an object of Student class Student s1 = new Student(); // get Class object using getClass() Class obj = s1.getClass(); // get the superclass of Student Class superClass = obj.getSuperclass(); System.out.println('Superclass of Student Class: ' + superClass.getName()); } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Yukarıdaki programlama örneğinde, bir Arayüz Kişi, yalnız bir yöntem olan 'display ()' ile tanımlanmıştır. Ardından kişi arayüzünü uygulayan bir Öğrenci sınıfı tanımlarız. Ana yöntemde, Class nesnesini almak için getClass () yöntemini kullanırız ve ardından getSuperClass () yöntemini kullanarak Student nesnesinin üst veya üst sınıfına erişiriz.
Arayüzleri Alın
Sınıf bazı arabirimleri uygularsa, bu arabirim adlarını java.lang.Class'ın getInterfaces () yöntemini kullanarak alabiliriz. Bunun için Java sınıfı üzerinde bir yansıma yapmamız gerekiyor.
Aşağıdaki programlama örneği, Java Reflection'da getInterfaces () yönteminin kullanımını tasvir etmektedir..
import java.lang.Class; import java.lang.reflect.*; //define Interface Animals and PetAnimals interface Animals { public void display(); } interface PetAnimals { public void makeSound(); } //define a class Dog that implements above interfaces class Dog implements Animals, PetAnimals { //define interface method display public void display() { System.out.println('This is a PetAnimal::Dog'); } //define interface method makeSound public void makeSound() { System.out.println('Dog makes sound::Bark bark'); } } class Main { public static void main(String() args) { try { // create an object of Dog class Dog dog = new Dog(); // get class object Class obj = dog.getClass(); // get the interfaces implemented by Dog Class() objInterface = obj.getInterfaces(); System.out.println('Class Dog implements following interfaces:'); //print all the interfaces implemented by class Dog for(Class citem : objInterface) { System.out.println('Interface Name: ' + citem.getName()); } } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Yukarıdaki programda, iki arayüz tanımladık, yani Hayvanlar ve PetAnimals. Sonra bu iki arayüzü de uygulayan bir Dog sınıfı tanımlarız.
Ana yöntemde yansıma yapmak için java.lang.Class içindeki Dog sınıfının nesnesini alıyoruz. Ardından, Dog sınıfı tarafından uygulanan arayüzleri almak için getInterfaces () yöntemini kullanırız.
Yansıma: Alan Değerini Alın
Daha önce belirtildiği gibi java.lang.reflect paketi, sınıfın alan veya veri üyelerini yansıtmamıza yardımcı olan Field sınıfını sağlar.
Aşağıda, bir alanın Yansıması için Field sınıfı tarafından sağlanan yöntemler listelenmiştir.
Yöntem | Açıklama |
---|---|
getField ('fieldName') | Alanı (genel) belirli bir alan adıyla döndürür. |
getFields () | Tüm genel alanları döndürür (hem sınıf hem de üst sınıf için). |
getDeclaredFields () | Sınıfın tüm alanlarını alır. |
getModifier () | Alanın erişim değiştiricisinin tamsayı gösterimini döndürür. |
set (classObject, değer) | Alana belirtilen değeri atar. |
get (classObject) | Alan değerini alır. |
setAccessible (boole) | True geçirerek özel alanı erişilebilir hale getirin. |
getDeclaredField ('fieldName') | Alanı belirtilen bir adla döndürür. |
Aşağıda, kamu ve özel alandaki yansımayı gösteren iki yansıma örneği verilmiştir.
Aşağıdaki Java programı, kamuya açık bir alandaki yansımayı göstermektedir.
import java.lang.Class; import java.lang.reflect.*; class Student { public String StudentName; } class Main { public static void main(String() args) { try{ Student student = new Student(); // get an object of the class Class Class obj = student.getClass(); // provide field name and get the field info Field student_field = obj.getField('StudentName'); System.out.println('Details of StudentName class field:'); // set the value of field student_field.set(student, 'Lacey'); // get the access modifier of StudentName int mod1 = student_field.getModifiers(); String modifier1 = Modifier.toString(mod1); System.out.println('StudentName Modifier::' + modifier1); // get the value of field by converting in String String typeValue = (String)student_field.get(student); System.out.println('StudentName Value::' + typeValue); } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Bu programda, ÖğrenciAdı genel alanına sahip bir sınıfı 'Öğrenci' ilan ettik. Daha sonra Field sınıfının API arayüzünü kullanarak StudentName alanında yansıtma gerçekleştirir ve erişim değiştiricisini ve değerini alırız.
Bir sonraki program, sınıfın özel bir alanı üzerinde düşünme gerçekleştirir. Özel alan için fazladan bir fonksiyon çağrısı yapılması dışında işlemler benzerdir. Özel alan için setAccessible (true) 'yu çağırmalıyız. Daha sonra bu alanda, kamusal alana benzer şekilde yansıtma yapıyoruz.
import java.lang.Class; import java.lang.reflect.*; class Student { private String rollNo; } class Main { public static void main(String() args) { try { Student student = new Student(); // get the object for class Student in a Class. Class obj = student.getClass(); // access the private field Field field2 = obj.getDeclaredField('rollNo'); // make the private field accessible field2.setAccessible(true); // set the value of rollNo field2.set(student, '27'); System.out.println('Field Information of rollNo:'); // get the access modifier of rollNo int mod2 = field2.getModifiers(); String modifier2 = Modifier.toString(mod2); System.out.println('rollNo modifier::' + modifier2); // get the value of rollNo converting in String String rollNoValue = (String)field2.get(student); System.out.println('rollNo Value::' + rollNoValue); } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Yansıma: Yöntem
Sınıfın alanlarına benzer şekilde, sınıf yöntemleri üzerinde yansıtma yapabilir ve çalışma zamanında davranışlarını değiştirebiliriz. Bunun için java.lang.reflect paketinin Method sınıfını kullanıyoruz.
Aşağıda, sınıf yönteminin Yansıması için Method sınıfı tarafından sağlanan işlevler listelenmiştir.
Yöntem | Açıklama |
---|---|
getMethods () | Sınıfta ve üst sınıfında tanımlanan tüm genel yöntemleri alır. |
getDeclaredMethod () | Sınıfta bildirilen yöntemleri döndürür. |
getName () | Yöntem adlarını döndürür. |
getModifiers () | Yöntemin erişim değiştiricisinin tamsayı gösterimini döndürür. |
getReturnType () | Yöntemin dönüş türünü döndürür. |
Aşağıdaki örnek, yukarıdaki API'leri kullanan Java'daki sınıf yöntemlerinin yansımasını göstermektedir.
import java.lang.Class; import java.lang.reflect.*; //declare a class Vehicle with four methods class Vehicle { public void display() { System.out.println('I am a Vehicle!!'); } protected void start() { System.out.println('Vehicle Started!!!'); } protected void stop() { System.out.println('Vehicle Stopped!!!'); } private void serviceVehicle() { System.out.println('Vehicle serviced!!'); } }class Main { public static void main(String() args) { try { Vehicle car = new Vehicle(); // create an object of Class Class obj = car.getClass(); // get all the methods using the getDeclaredMethod() in an array Method() methods = obj.getDeclaredMethods(); // for each method get method info for(Method m : methods) { System.out.println('Method Name: ' + m.getName()); // get the access modifier of methods int modifier = m.getModifiers(); System.out.print('Modifier: ' + Modifier.toString(modifier) + ' '); // get the return type of method System.out.print('Return Type: ' + m.getReturnType()); System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Yukarıdaki programda, getDeclaredMethods yönteminin sınıf tarafından bildirilen yöntem dizisini döndürdüğünü görüyoruz. Daha sonra bu diziyi yineleriz ve her yöntemin bilgilerini görüntüleriz.
Yansıma: Yapıcı
Bir Java sınıfının yapıcılarını incelemek ve değiştirmek için java.lang.reflect paketinin 'Constructor' sınıfını kullanabiliriz.
Yapıcı sınıfı, bu amaç için aşağıdaki yöntemleri sağlar.
Yöntem | Açıklama |
---|---|
getConstructors () | Sınıfta ve üst sınıfında bildirilen tüm yapıcıları döndürür. |
getDeclaredConstructor () | Bildirilen tüm kurucuları döndürür. |
getName () | Yapıcının adını alır. |
getModifiers () | Yapıcıların erişim değiştiricisinin tamsayı temsilini döndürür. |
getParameterCount () | Yapıcılar için toplam parametre sayısını döndürür. |
Aşağıdaki yansıma örneği, Java'daki bir sınıfın kurucularının yansımasını göstermektedir. Yöntem yansıması gibi, burada da getDeclaredConstructors yöntemi bir sınıf için bir yapıcı dizisi döndürür. Daha sonra, her kurucu hakkındaki bilgileri görüntülemek için bu yapıcı dizisini dolaşırız.
import java.lang.Class; import java.lang.reflect.*; //declare a class Person with three constructors class Person { public Person() { } //constructor with no parameters public Person(String name) { } //constructor with 1 parameter private Person(String name, int age) {} //constructor with 2 parameters } class Main { public static void main(String() args) { try { Person person = new Person(); Class obj = person.getClass(); // get array of constructors in a class using getDeclaredConstructor() Constructor() constructors = obj.getDeclaredConstructors(); System.out.println('Constructors for Person Class:'); for(Constructor c : constructors) { // get names of constructors System.out.println('Constructor Name: ' + c.getName()); // get access modifier of constructors int modifier = c.getModifiers(); System.out.print ('Modifier: ' + Modifier.toString(modifier) + ' '); // get the number of parameters in constructors System.out.println('Parameters: ' + c.getParameterCount()); //if there are parameters, get parameter type of each parameter if(c.getParameterCount() > 0){ Class() paramList=c.getParameterTypes(); System.out.print ('Constructor parameter types :'); for (Class class1 : paramList) { System.out.print(class1.getName() +' '); } } System.out.println('
'); } } catch(Exception e) { e.printStackTrace(); } } }
Çıktı
Yansımanın Dezavantajları
Yansıma güçlüdür, ancak ayrım gözetmeksizin kullanılmamalıdır. Yansıma kullanmadan çalışmak mümkünse, kullanmaktan kaçınmak tercih edilir.
Aşağıda, Düşüncenin birkaç dezavantajı listelenmiştir:
- Performans Ek Yükü: Yansıtma güçlü bir özellik olsa da, yansıtıcı işlemler hala yansıtmasız işlemlerden daha yavaş performansa sahiptir. Bu nedenle performans açısından kritik uygulamalarda yansımalar kullanmaktan kaçınmalıyız.
- Güvenlik Kısıtlamaları: Yansıma bir çalışma zamanı özelliği olduğundan, çalışma zamanı izinleri gerektirebilir. Bu nedenle, kodun kısıtlı bir güvenlik ayarında yürütülmesini gerektiren uygulamalar için yansıtma işe yaramayabilir.
- Dahili Ürünlerin Maruz Kalması: Yansıma kullanarak, bir sınıftaki özel alanlara ve yöntemlere erişebiliriz. Böylece yansıma, kodu taşınabilir ve işlevsiz hale getirebilecek soyutlamayı kırar.
Sıkça Sorulan Sorular
S # 1) Java'da Yansıma neden kullanılıyor?
Cevap: Yansıma kullanarak, derleme zamanında anonim olsalar bile çalışma zamanında sınıfları, arayüzleri, yapıcıları, alanları ve yöntemleri inceleyebiliriz. Bu inceleme, bu varlıkların davranışını çalışma zamanında değiştirmemize olanak tanır.
S # 2) Yansıma nerede kullanılır?
Cevap: Yansıma, kullanıcı tanımlı sınıflarla birlikte çalışan, programcının sınıfların veya diğer varlıkların ne olacağını bile bilmediği yazı çerçevelerinde kullanılır.
S # 3) Java Yansıması yavaş mı?
Cevap: Evet, yansımasız koddan daha yavaştır.
S # 4) Java Yansıması kötü mü?
Cevap: Bir bakıma evet. Her şeyden önce, derleme zamanı güvenliğini kaybediyoruz. Derleme zamanı güvenliği olmadan, son kullanıcıları etkileyebilecek çalışma zamanı hataları alabiliriz. Hatayı gidermek de zor olacaktır.
S # 5) Java'da bir Düşünceyi nasıl durdurursunuz?
Cevap: Yansıma dışı işlemler yazarak yansıma kullanmaktan kaçınırız. Ya da belki yansımalı özel bir doğrulama gibi bazı genel mekanizmaları kullanabiliriz.
Java Reflection Hakkında Daha Fazla Bilgi
java.lang.reflect paketi, yansıtma yapacak sınıflara ve arayüzlere sahiptir. Ve java.lang.class, yansıma için bir giriş noktası olarak kullanılabilir.
Sınıf nesneleri nasıl alınır:
1. Bir nesnenin örneğine sahipseniz,
sınıf c = obj.getclass ();
2. Sınıfın türünü biliyorsanız,
sınıf c = type.getClass ();
3. Sınıf adını biliyorsanız,
Sınıf c = Class.forName ('com.demo.Mydemoclass');
Sınıf üyeleri nasıl edinilir:
Sınıf üyeleri alanlar (sınıf değişkenleri) ve yöntemlerdir.
- getFields () - Özel alanlar dışındaki tüm alanları almak için kullanılır.
- getDeclaredField () - Özel alanları almak için kullanılır.
- getDeclaredFields () - Özel ve kamusal alanları almak için kullanılır.
- getMethods () - Özel yöntemler dışındaki tüm yöntemleri almak için kullanılır.
- getDeclaredMethods () –Genel ve özel yöntemleri elde etmek için kullanılır.
Demo Programları:
ReflectionHelper.java:
Yansıma API'sini kullanarak inceleyeceğimiz sınıf budur.
ücretsiz anime izlemek için en iyi site
class ReflectionHelper { private int age; private String name; public String deptName; public int empID; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDeptName() { return deptName; } public void setDeptName(String deptName) { this.deptName = deptName; } }
ReflectionDemo.java
public class ReflectionDemo { public static void main(String() args) throws NoSuchFieldException, SecurityException { //get the class Class ReflectionHelperclass=ReflectionHelper.class; //get the name of the class String className = ReflectionHelperclass.getName(); System.out.println('className=='+className); System.out.println('getModifiers'+ReflectionHelperclass.getModifier s()); System.out.println('getSuperclass'+ReflectionHelperclass.getSupercla ss()); System.out.println('getPackage'+ReflectionHelperclass.getPackage()); Field() fields =ReflectionHelperclass.getFields(); //getting only the public fields for(Field oneField : fields) { Field field = ReflectionHelperclass.getField(oneField.getName()); String fieldname = field.getName(); System.out.println('only the public fieldnames:::::'+fieldname); } //getting all the fields of the class Field() privatefields =ReflectionHelperclass.getDeclaredFields(); for(Field onefield : privatefields) { Field field = ReflectionHelperclass.getDeclaredField(onefield.getName()); String fieldname = field.getName(); System.out.println('all the fieldnames in the class:::'+fieldname); } Method() methods =ReflectionHelperclass.getDeclaredMethods(); for(Method m: methods) { System.out.println('methods::::'+m.getName()); } }}
Sonuç
Bu eğitimde Java'daki Reflection API ayrıntılı olarak açıklanmıştır. Sınıfların, arabirimlerin, alanların, yöntemlerin ve kurucuların yansımasının birkaç dezavantajla birlikte nasıl gerçekleştirileceğini gördük.
Yansıma, Java'da nispeten gelişmiş bir özelliktir, ancak dil üzerinde bir gücü olan programcılar tarafından kullanılmalıdır. Bunun nedeni, dikkatli kullanılmaması durumunda beklenmeyen hatalara ve sonuçlara neden olabilmesidir.
Yansıma güçlü olsa da dikkatli kullanılmalıdır. Bununla birlikte, yansıma kullanarak çalışma zamanına kadar sınıflardan ve diğer varlıklardan habersiz uygulamalar geliştirebiliriz.
=> Java Yeni Başlayanlar Kılavuzuna Bir Göz Atın.
Önerilen Kaynaklar
- Örneklerle Java Tarayıcı Sınıfı Eğitimi
- Java Tamsayı ve Java BigInteger Sınıfı Örneklerle
- Yeni Başlayanlar İçin JAVA Eğitimi: 100+ Uygulamalı Java Video Eğitimi
- Java Programlama Diline Giriş - Video Eğitimi
- Java Vektör Nedir | Örneklerle Java Vektör Sınıfı Eğitimi
- Java Arayüzü ve Örneklerle Soyut Sınıf Eğitimi
- Java substring () Yöntemi - Örneklerle Eğitim
- Java Collections Framework (JCF) Eğitimi