Salam, ýaş Padawan. Bu makalada java programmistleriniň güýji diňe umytsyz ýaly görünýän güýçde ulanýan Güýç hakda aýdaryn. Şeýlelikde, Java-yň garaňky tarapy -
Java-da şöhlelenme Java Reflection API ulanyp amala aşyrylýar. Bu şöhlelenme näme? Gysga we takyk kesgitleme bar, ol internetde hem meşhur. Oýlanma (Latyn latyn refleksiýasyndan - yza gaýdyp barmak) bir programma ýerine ýetirilende maglumatlary öwrenmek üçin mehanizmdir. Oýlanma, meýdanlar, usullar we synp gurluşykçylary baradaky maglumatlary gözden geçirmäge mümkinçilik berýär. Oýlanmak mehanizminiň özi düzmek wagtynda ýok, ýöne programma ýerine ýetirilende ýüze çykan görnüşleri gaýtadan işlemäge mümkinçilik berýär. Eralňyşlyklary habar bermek üçin oýlanmak we logiki taýdan sazlaşykly modeliň bolmagy dogry dinamiki kod döretmäge mümkinçilik berýär. Başgaça aýdylanda, java-da şöhlelenmäniň nähili işleýändigine düşünmek size birnäçe ajaýyp mümkinçilikleri açýar. Göçme manyda Sapaklary we olaryň böleklerini birleşdirip bilersiňiz.
Ine, şöhlelenmäniň nämäniň rugsat berýändiginiň esasy sanawy:
Ierarhiýamda
Reflection API
- Obýektiň synpyny tapmak / kesgitlemek;
- Synp üýtgedijileri, meýdanlary, usullary, yzygiderliligi, konstruktorlary we superklasslary barada maglumat alyň;
- Geçirilen interfeýslere / interfeýslere haýsy usullara degişlidigini anyklaň;
- Synpyň mysalyny dörediň we programma ýerine ýetirilýänçä synpyň ady belli däl;
- Obýekt meýdanynyň bahasyny alyň we belläň;
- Obýektiň usulyna at bilen jaň ediň.
MyClass
:
public class MyClass {
private int number;
private String name = "default";
// public MyClass(int number, String name) {
// this.number = number;
// this.name = name;
// }
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public void setName(String name) {
this.name = name;
}
private void printData(){
System.out.println(number + name);
}
}
Görşümiz ýaly, bu iň köp ýaýran synp. Parametrleri bolan konstruktor bir sebäbe görä düşündirilýär, bu meselä soňrak dolanarys. Synpyň mazmunyna ýakyndan göz aýlasaň, belki, getter
a üçin a ýoklugyny görersiň name
. Meýdanyň özi name
giriş üýtgediji bilen bellendi private
, biz synpyň daşynda girip bilmeris, =>
bahasyny alyp bilmeris. "Onda näme problema bar? - sen diýýäñ. " getter
Giriş modifikatoryny goşuň ýa-da üýtgediň." Dogry aýdarsyňyz, ýöne MyClass
düzülen aar kitaphanasynda ýa-da girişi redaktirlemän başga bir ýapyk modulda bolsa we iş ýüzünde bu ýygy-ýygydan bolýar. Käbir ünssiz programmist ýazmagy ýatdan çykardy getter
. Oýlanmak hakda ýatlamagyň wagty geldi! Synp private
meýdanyna çykmaga synanyşalyň : name
MyClass
public static void main(String[] args) {
MyClass myClass = new MyClass();
int number = myClass.getNumber();
String name = null; //no getter =(
System.out.println(number + name);//output 0null
try {
Field field = myClass.getClass().getDeclaredField("name");
field.setAccessible(true);
name = (String) field.get(myClass);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(number + name);//output 0default
}
Geliň indi bu ýerde näme bolandygyny anyklalyň. Java-da ajaýyp synp bar Class
. Executerine ýetirilýän Java programmasynda synplary we interfeýsleri görkezýär. Class
Arasyndaky baglanyşyga degip bilmeris ClassLoader
. bu makalanyň mowzugy däl. Ondan soň, bu synpyň meýdanlaryny almak üçin usula jaň etmeli getFields()
, bu usul synpyň bar bolan meýdanlaryna bize gaýdyp geler. Bu, biziň üçin amatly däl, sebäbi meýdançamyz private
, şonuň üçin usuly ulanýarys getDeclaredFields()
. Bu usul bir topar synp meýdanlaryny hem gaýtaryp berýär, ýöne indi ikisi private
hem protected
. Biziň ýagdaýymyzda, bizi gyzyklandyrýan meýdanyň adyny bilýäris we islenýän meýdanyň ady getDeclaredField(String)
nirede bolsa usuly ulanyp bileris.String
Bellik: getFields()
getDeclaredFields()
ene-atalar synpynyň meýdanlaryny yzyna gaýtarmaň ! Field
Ajaýyp, özümize baglanyşyk bolan bir obýekt aldyk name
. Sebäbi meýdan публичным
(köpçülik) däldi, onuň bilen işlemek üçin ygtyýar berilmeli. Usul setAccessible(true)
bize işlemegi dowam etdirmäge mümkinçilik berýär. Indi meýdan name
doly gözegçilikde! Biziň synpymyzyň mysaly bolan obýekte get(Object)
jaň edip, onuň bahasyny alyp bilersiňiz . Ony zyňýarys we üýtgeýjimize belläris . Birden 'a' ýok bolsa , at meýdany üçin täze baha bellemek üçin usuly ulanyp bileris : Field
Object
MyClass
String
name
setter
set
field.set(myClass, (String) "new value");
Gutlaýarys! Justaňy şöhlelenmegiň esasy mehanizmini özleşdirdiňiz we meýdana girip bildiňiz private
! Bloklara try/catch
we ulanylýan kadadan çykma görnüşlerine üns beriň. IDE-iň özi hökmany barlygyny görkezer, ýöne olaryň adynyň bu ýere gelmeginiň sebäbini görkezýär. Dowam et! Üns beren bolsaňyz, MyClass
synp maglumatlarymyz barada maglumatlary görkezmek üçin eýýäm bir usulymyz bar:
private void printData(){
System.out.println(number + name);
}
Emma bu programmist bu ýerde-de miras galdyrdy. Usul giriş üýtgeýjisiniň aşagyndady private
we her gezek çykyş koduny özümiz ýazmaly bolduk. Bu tertipli däl, pikirimiz nirede? ... Geliň, aşakdaky funksiýany ýazalyň:
public static void printData(Object myClass){
try {
Method method = myClass.getClass().getDeclaredMethod("printData");
method.setAccessible(true);
method.invoke(myClass);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
Bu ýerde prosedura takmynan bir meýdan almak bilen deňdir - islenýän usuly at bilen alýarys we oňa girýäris. Method
Ulanylýan obýektimize jaň etmek üçin invoke(Оbject, Args)
, Оbject
synpyň mysaly hem bar MyClass
. Args
- usul argumentleri - biziňkiler ýok. Indi maglumatlary görkezmek üçin funksiýany ulanýarys printData
:
public static void main(String[] args) {
MyClass myClass = new MyClass();
int number = myClass.getNumber();
String name = null; //?
printData(myClass); // outout 0default
try {
Field field = myClass.getClass().getDeclaredField("name");
field.setAccessible(true);
field.set(myClass, (String) "new value");
name = (String) field.get(myClass);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
printData(myClass);// output 0new value
}
Hurray, indi synpyň hususy usulyna girip bileris. Methodöne bu usulda henizem argumentler bar bolsa we näme üçin teswirli konstruktor bar? Her zadyň wagty bar. Ilkibaşdaky kesgitlemeden, şöhlelenmäniň size re modeimde runtime
(programma işleýän wagtynda) synp mysallaryny döretmäge mümkinçilik berýändigi düşnüklidir! Şol synpyň doly hünärli ady bilen synpyň obýektini döredip bileris. Doly hünärli synpyň ady, oňa barýan ýoly göz öňünde tutup, synpyň adydyr package
.
package
doly ady MyClass
“” bolar reflection.MyClass
. Şeýle hem synpyň adyny ýönekeý usulda tapyp bilersiňiz (synpyň adyny setir hökmünde yzyna getirer):
MyClass.class.getName()
Oýlanmak arkaly synpyň mysalyny döredeliň:
public static void main(String[] args) {
MyClass myClass = null;
try {
Class clazz = Class.forName(MyClass.class.getName());
myClass = (MyClass) clazz.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
System.out.println(myClass);//output created object reflection.MyClass@60e53b93
}
Java programmasy başlan wagty hemme synplar JVM-e ýüklenenok. Koduňyz klasa degişli däl bolsa MyClass
, sapaklary JVM-e ýüklemek üçin jogapkär adam, ýagny ClassLoader
hiç haçan ol ýere ýüklemez. ClassLoader
Şol sebäpden, üýtgeýän görnüş görnüşinde synpymyzyň beýanyny ýüklemäge we almaga mejbur etmeli Class
. Bu ýumuş üçin, düşündiriş talap edýän synpyň ady nirede, forName(String)
bir usul bar . String
Alnansoň , şol bir düşündirişe görä dörediljek Сlass
usul jaňy newInstance()
gaýdyp geler . Object
Bu obýekti synpymyza getirmek galýar MyClass
. Salkyn! Kyn boldy, ýöne düşnükli diýip umyt edýärin. Indi sözüň doly manysynda bir setirden mysal döredip bileris! Gynansagam, beýan edilen usul diňe deslapky konstruktor bilen işleýär (parametrlersiz). Argumentler we parametrler bilen konstruktorlar bilen usullary nädip çagyrmaly? Gurluşykçymyzy aýyrmagyň wagty geldi. Garaşylyşy ýaly, newInstance()
deslapky konstruktory tapmaýar we indi işlemeýär. Synp mysalynyň döredilmegini täzeden ýazalyň:
public static void main(String[] args) {
MyClass myClass = null;
try {
Class clazz = Class.forName(MyClass.class.getName());
Class[] params = {int.class, String.class};
myClass = (MyClass) clazz.getConstructor(params).newInstance(1, "default2");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
System.out.println(myClass);//output created object reflection.MyClass@60e53b93
}
Synp konstruktorlaryny almak üçin usuly synp synpyndan çagyryň getConstructors()
we konstruktoryň parametrlerini almak üçin jaň ediň getParameterTypes()
:
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
Class[] paramTypes = constructor.getParameterTypes();
for (Class paramType : paramTypes) {
System.out.print(paramType.getName() + " ");
}
System.out.println();
}
Şeýlelik bilen, ähli konstruktorlary we ähli parametrleri olara alýarys. Mysal üçin, belli, eýýäm belli parametrleri bolan belli bir konstruktora jaň bar. newInstance
Bu konstruktory çagyrmak üçin bu parametrleriň bahalaryny kesgitleýän usuly ulanýarys . invoke
Çagyryş usullary üçin hem şeýle bolar . Sorag ýüze çykýar: gurluşykçylaryň şöhlelendiriji çagyryşy nirede peýdaly bolup biler? Başda aýdylyşy ýaly häzirki zaman java tehnologiýalary, Reflection API bolmasa edip bilmez. Mysal üçin, DI (Dependency Injection), bu ýerde düşündirişler usullaryň we konstruktorlaryň şöhlelenmesi bilen utgaşyp, Android ösüşinde meşhur bolan Dagger kitaphanasyny emele getirýär. Bu makalany okanyňyzdan soň, “Reflection API” mehanizmlerinde özüňizi ýagtylandyryp bilersiňiz. Munuň üçin “java” -yň garaňky tarapy diýilýär. OOP paradigmasyny düýbünden bozýar. Java-da, encapsulation käbir programma bölekleriniň beýlekilerine elýeterliligini gizlemek we çäklendirmek üçin hyzmat edýär. Hususy üýtgedijini ulanmak bilen, bu meýdana girmek diňe bu meýdanyň bar bolan synpynda boljakdygyny aňladýarys, şonuň esasynda programmanyň mundan beýläkki arhitekturasyny gurýarys. Bu makalada, islendik ýere barmak üçin şöhlelenmäni nädip ulanyp boljakdygyny gördük. Binagärlik çözgüdi görnüşinde oňat mysal döredijilik dizaýn nagşydyr - Singleton
. Esasy pikiri, programmanyň tutuş işinde bu şablony amala aşyrýan synpyň diňe bir nusgasy bolmaly. Bu, deslapky giriş üýtgedijisini konstruktor üçin şahsylaşdyrmak arkaly amala aşyrylýar. Käbir programmist öz pikiri bilen şeýle sapaklary döretse gaty erbet bolar. Theeri gelende aýtsak, ýaňy-ýakynda işgärimden eşiden gaty gyzykly bir sorag bar: şablony amala aşyrýan synpyň Singleton
mirasdüşerleri bolup bilermi? Bu ýagdaýda hatda pikirlenmegiň hem güýji ýokmy? Makala baradaky pikiriňizi we jogabyňyzy teswirlerde ýazyň we soraglaryňyzy beriň! “Reflection API” -niň hakyky güýji “Runtime Annotations” bilen utgaşýar, bu hakda geljekde Java-yň garaňky tarapy hakda gürleşeris. Üns bereniňiz üçin sag boluň!
GO TO FULL VERSION