Объект хандлагат програмчлалын хэл  Java Хичээл :  CS203 Улирал :  2010  хавар Бэлтгэсэн багш :   Д.Энхжаргал Mongolia University of Science & Technology Лабораторийн ажил №  9 Reflection Оноо: 3
Reflection Даалгавар: Оюутан бүр өөрийн сонгосон сэдэвтээ тохируулан бодлогын даалгавраа өөрөө хийсвэрлэж  ( өөрийн гэсэн нэг класс сонгож )  хожуу холболтыг хэрэгжүүлсэн жижиг хэмжээний програм бичих.  Онолын хувд: Эрт холболт  (Early binding)  нь компиляцын үед дуудагдах функцуудыг мэдэгдэж байхыг шаарддаг. Түүнийг заримдаа статик холболт  (static binding)  ч гэж нэрлэдэг. Эрт холболт нь компиляцын үед ямар функц дуудагдах нь мэдэгдэж байдаг учраас холболтыг компиляцын явцад  (compile time)  хийж өгдөг.  Хожуу холболт  (late binding)  :  Java  програм нь гишүүн функцуудыг биелэх үед нь динамик зохион байгуулалттайгаар дууддаг. Үүнийг хожуу холболт  (late binding)  гэнэ. Хожуу холболтыг динамик холболт  (dynamic binding)  ч гэж заримдаа нэрлэдэг. Хожуу холболтын үед компиляцын үед ямар функц дуудагдах нь тодорхойгүй байдаг учраас холболтыг биелэлтийн явцад  (run- time)  хийж өгдөг.  Шаардлага:  Бодлогын даалгавар нь бодит амьдралд нийцсэн байх.  Бүрэлдэхүүн класс
Класс/интерфейсийн тодорхойлогч public class Student  {…}  эсвэл public interface Cafe  {…} Interface   Cafe   extends  University   { …}  эсвэл   public class Student  extends  Person   { …} Interface   Cafe  extends   University   { …}  эсвэл   public class Student extends  Person   { …} print_method_or_constructor()  гэсэн статик функцын тусламжтай байгуулагч функцуудын мэдээлэл харах print_field()  гэсэн статик функцын тусламжтай гишүүн өгөгдлийн талаарх мэдээлэл харах print_method_or_constructor()  гэсэн статик функцын тусламжтай   гишүүн функцын талаарх мэдээлэл харах java.lang.reflect   пакет дахь классыг импортлох Дэлгэрэнгүй харахыг хүссэн класс/интерфейсийнхээ нэрийг програмд 0-р аргумент болгон дамжуулах
Жишээ  (Reflection) : Классын гишүүдтэй танилцах Энд ашиглагдсан функцууд Class  классын  isInterface();   -  Тухайн  object reference type  нь интерфейс эсэхийг шалгах функц getModifiers();   -Тухайн класс/интерфейсийн хандалтыг тодорхойлогчийг унших getName();   -Тухайн класс/интерфейсийн нэрийг унших getSuperclass();  -  Тухайн класс/интерфейсийн эх классыг буцаах getInterfaces();   -  Тухайн класс/ интерфейстэй холбогдсон интерфейсүүдийг буцаах getDeclaredConctructors();   - Тухайн классд тодорхойлогдсон байгуулагч функцуудыг буцаах getDeclaredFileds();   - Тухайн классд тодорхойлогдсон гишүүн өгөгдлүүдийг буцаах   getDeclaredMethods();   - Тухайн классд тодорхойлогдсон гишүүн функцуудыг буцаах
Төрөл хувиргалт
Энд ашиглагдсан функцууд Class  классын  isArray();   -  Тухайн  object reference type  нь массив эсэхийг шалгах функц Field  классын  getModifiers();   -Тухайн гишүүн өгөгдлийн хандалтыг тодорхойлогчийг буцаах getType();   -Тухайн гишүүн өгөгдлийн төрлийг буцаах getName();  -  Тухайн гишүүн өгөгдлийн нэрийг буцаах Method  классын  getReturnType();   -  Тухайн гишүүн функцын буцаах утгыг буцаах getParameterTypes();   - Тухайн гишүүн функцын парамет - рүүдийн төрлүүдийг буцаах getExceptionTypes();   - Тухайн гишүүн функцын хаях онцгой тохиолдлуудын төрлүүдийг буцаах Constructor  классын getParameterTypes();   - Тухайн байгуулагч функцын   парамет - рүүдийн төрлүүдийг буцаах getExceptionTypes();   - Тухайн байгуулагч функцын хаях онцгой   тохиолдлуудын төрлүүдийг буцаах
Reflection  of  Student class ҮР ДҮН: ShowClass.java
Reflection  of  University interface ҮР ДҮН: ShowClass.java
Жишээ  (Reflection) :  Invoking method dynamically Тухайн классаас харгалзах   гишүүн функцыг унших   getMethod(methodname, parameters); Тухайн гишүүн функцыг динамикаар холбож ажлуулах  methodname.invoke(target, arguments);
Жишээ:  Reflection  Багш  (Teacher)  классыг авч үзъе. Одоо түүний объектуудыг тодорхойлъё : Энэ тохиолдолд бид Сургууль  (School)  классыг сайтар мэдэх бөгөөд түүн рүү кодчилолын явцад хандаж чадна. Хэрэв Сургууль  (School)  классд зарим өөрчлөлт орвол  ( гишүүн функц нь өөрчлөгдөх эсвэл шинээр нэмэгдэнэ гэж үзвэл )  бид кодоо дахин бичих шаардлага гарна. package csms.sw203.school; public class School { private String name; private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return name + " at " + address; } } School school  = new School(); school.setName("KTMC"); school.setAddress("Sansar, UB, Mongolia");
Reflection  хэмээх ойлголтын тусламжтай бид тэдгээр асуудлыг хялбар аргаар шийдэж болно.   Reflection  нь биднийг танил бус классуудтайгаа ажиллах боломжийг бүрдүүлэх бөгөөд кодын өөрчлөлтийг төвөггүйхэн хийх боломжтой болно. Жишээ:  Reflection  public class ReflectionTestClass1 { public static void main(String[] args) throws Exception { ReflectionTestClass1 test = new ReflectionTestClass1(); test.createSchool(); } private void createSchool() throws Exception { Properties prop = new Properties(); prop.load(this.getClass().getResourceAsStream("school.properties")); Object object = Class.forName("csms.sw203.school.School").newInstance(); Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName,    new Class[]{String.class}); method.invoke(object, new Object[]{value}); } System.out.println(object); } } String -ээс класс үүсгэх Шинэ объектыг динамикаар үүсгэх Гишүүн функцыг динамикаар тодорхойлох Функцыг динамикаар холбох
createSchool()   фунцыг дэлгэрэнгүй авч үзье. Дээрх 2 мөр нь  CLASSPATH  –аас  “school.properties”  текст файлыг ачаалдаг. Properties  гэдэг нь  Java  класс юм. Түүнийг  “properties”  нэртэй текст файлд хадгалах бөгөөд дараах форматтай.  name=value Энэхүү  Properties  класс нь  “names”  болон  “values” -ийг тодорхойлох функцээр хангагдсан. this.getClass().getResourceAsStream("school.properties")  гэсэн мөрөнд тухайн идэвхитэй замаас  School.properties  файлын агуулгыг унших Дээрх мөр нь  reflection -той холбоотой 2 онцлогийг ашиглана.   dynamic class loading   ба   dynamic instantiation . Class.forName("csms.sw203.school.School")  мөр нь  JVM -д “ csms.sw203.school ” нэртэй пакетаас  "School“  нэртэй классыг хайж олоод санах ойд ачааллах үүрэг өгнө. Үр дүнд нь динамкаар ачаалагдсан классын объектыг буцааана. Жишээ:  Reflection  Properties prop = new Properties(); prop.load(this.getClass().getResourceAsStream("school.properties")); Object object = Class.forName("csms.sw203.school.School").newInstance();
Дээрх мөрөнд объектыг динамикаар үүсгэж байна. Бид  Properties  файлаас хүссэн утгаа хайж олохын тулд түлхүүр  (key)  ашиглах шаардлагатай. Энэ түлхүүр нь  Properties  файл дахь  name  хэсэг юм. Жишээ:  Reflection  Object object = Class.forName("csms.sw203.school.School").newInstance(); Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); ... ... }
Дээр  schoool.properties  файлын агуулгыг үзүүлсэн байна . property  бүрт харгалзах  setter  функцыг  School  классд тодорхойлсон. Жишээ нь. name    setName() address    setAddress() Давталтын  3 мөрөнд  property key -д харгалзах функцын нэрийг гаргаж авч байна 4 мөрөнд тухайн классаас тухайн нэрт харгалзах функцын нэрийг динамикаар тодорхойлж байна 5 мөрөнд уг функцыг динамикаар холбож ажлуулж байна Жишээ:  Reflection  name=KTMC address=Sansar, Ulaanbaator, Mongolian Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName, new Class[]{String.class}); method.invoke(object, new Object[]{value}); }
Давталт дахь сүүлчийн 2 мөрөнд анхаарлаа хандуулъя Функц гэдэгт тухайн функцын нэрээс гадна параметрүүдийг хамтад нь авч үздэг.  Хэдийгээр функцын нэр нь адил боловч параметрийн төрлөөрөө ялгаатай бол харгалзах функцыг цааш хайх шаардлага гарна. Жишээ:  Reflection  Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName, new Class[]{String.class}); method.invoke(object, new Object[]{value}); }

SW203 Lab9

  • 1.
    Объект хандлагат програмчлалынхэл Java Хичээл : CS203 Улирал : 2010 хавар Бэлтгэсэн багш : Д.Энхжаргал Mongolia University of Science & Technology Лабораторийн ажил № 9 Reflection Оноо: 3
  • 2.
    Reflection Даалгавар: Оюутанбүр өөрийн сонгосон сэдэвтээ тохируулан бодлогын даалгавраа өөрөө хийсвэрлэж ( өөрийн гэсэн нэг класс сонгож ) хожуу холболтыг хэрэгжүүлсэн жижиг хэмжээний програм бичих. Онолын хувд: Эрт холболт (Early binding) нь компиляцын үед дуудагдах функцуудыг мэдэгдэж байхыг шаарддаг. Түүнийг заримдаа статик холболт (static binding) ч гэж нэрлэдэг. Эрт холболт нь компиляцын үед ямар функц дуудагдах нь мэдэгдэж байдаг учраас холболтыг компиляцын явцад (compile time) хийж өгдөг. Хожуу холболт (late binding) : Java програм нь гишүүн функцуудыг биелэх үед нь динамик зохион байгуулалттайгаар дууддаг. Үүнийг хожуу холболт (late binding) гэнэ. Хожуу холболтыг динамик холболт (dynamic binding) ч гэж заримдаа нэрлэдэг. Хожуу холболтын үед компиляцын үед ямар функц дуудагдах нь тодорхойгүй байдаг учраас холболтыг биелэлтийн явцад (run- time) хийж өгдөг. Шаардлага: Бодлогын даалгавар нь бодит амьдралд нийцсэн байх. Бүрэлдэхүүн класс
  • 3.
    Класс/интерфейсийн тодорхойлогч publicclass Student {…} эсвэл public interface Cafe {…} Interface Cafe extends University { …} эсвэл public class Student extends Person { …} Interface Cafe extends University { …} эсвэл public class Student extends Person { …} print_method_or_constructor() гэсэн статик функцын тусламжтай байгуулагч функцуудын мэдээлэл харах print_field() гэсэн статик функцын тусламжтай гишүүн өгөгдлийн талаарх мэдээлэл харах print_method_or_constructor() гэсэн статик функцын тусламжтай гишүүн функцын талаарх мэдээлэл харах java.lang.reflect пакет дахь классыг импортлох Дэлгэрэнгүй харахыг хүссэн класс/интерфейсийнхээ нэрийг програмд 0-р аргумент болгон дамжуулах
  • 4.
    Жишээ (Reflection): Классын гишүүдтэй танилцах Энд ашиглагдсан функцууд Class классын isInterface(); - Тухайн object reference type нь интерфейс эсэхийг шалгах функц getModifiers(); -Тухайн класс/интерфейсийн хандалтыг тодорхойлогчийг унших getName(); -Тухайн класс/интерфейсийн нэрийг унших getSuperclass(); - Тухайн класс/интерфейсийн эх классыг буцаах getInterfaces(); - Тухайн класс/ интерфейстэй холбогдсон интерфейсүүдийг буцаах getDeclaredConctructors(); - Тухайн классд тодорхойлогдсон байгуулагч функцуудыг буцаах getDeclaredFileds(); - Тухайн классд тодорхойлогдсон гишүүн өгөгдлүүдийг буцаах getDeclaredMethods(); - Тухайн классд тодорхойлогдсон гишүүн функцуудыг буцаах
  • 5.
  • 6.
    Энд ашиглагдсан функцуудClass классын isArray(); - Тухайн object reference type нь массив эсэхийг шалгах функц Field классын getModifiers(); -Тухайн гишүүн өгөгдлийн хандалтыг тодорхойлогчийг буцаах getType(); -Тухайн гишүүн өгөгдлийн төрлийг буцаах getName(); - Тухайн гишүүн өгөгдлийн нэрийг буцаах Method классын getReturnType(); - Тухайн гишүүн функцын буцаах утгыг буцаах getParameterTypes(); - Тухайн гишүүн функцын парамет - рүүдийн төрлүүдийг буцаах getExceptionTypes(); - Тухайн гишүүн функцын хаях онцгой тохиолдлуудын төрлүүдийг буцаах Constructor классын getParameterTypes(); - Тухайн байгуулагч функцын парамет - рүүдийн төрлүүдийг буцаах getExceptionTypes(); - Тухайн байгуулагч функцын хаях онцгой тохиолдлуудын төрлүүдийг буцаах
  • 7.
    Reflection of Student class ҮР ДҮН: ShowClass.java
  • 8.
    Reflection of University interface ҮР ДҮН: ShowClass.java
  • 9.
    Жишээ (Reflection): Invoking method dynamically Тухайн классаас харгалзах гишүүн функцыг унших getMethod(methodname, parameters); Тухайн гишүүн функцыг динамикаар холбож ажлуулах methodname.invoke(target, arguments);
  • 10.
    Жишээ: Reflection Багш (Teacher) классыг авч үзъе. Одоо түүний объектуудыг тодорхойлъё : Энэ тохиолдолд бид Сургууль (School) классыг сайтар мэдэх бөгөөд түүн рүү кодчилолын явцад хандаж чадна. Хэрэв Сургууль (School) классд зарим өөрчлөлт орвол ( гишүүн функц нь өөрчлөгдөх эсвэл шинээр нэмэгдэнэ гэж үзвэл ) бид кодоо дахин бичих шаардлага гарна. package csms.sw203.school; public class School { private String name; private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String toString() { return name + " at " + address; } } School school = new School(); school.setName("KTMC"); school.setAddress("Sansar, UB, Mongolia");
  • 11.
    Reflection хэмээхойлголтын тусламжтай бид тэдгээр асуудлыг хялбар аргаар шийдэж болно. Reflection нь биднийг танил бус классуудтайгаа ажиллах боломжийг бүрдүүлэх бөгөөд кодын өөрчлөлтийг төвөггүйхэн хийх боломжтой болно. Жишээ: Reflection public class ReflectionTestClass1 { public static void main(String[] args) throws Exception { ReflectionTestClass1 test = new ReflectionTestClass1(); test.createSchool(); } private void createSchool() throws Exception { Properties prop = new Properties(); prop.load(this.getClass().getResourceAsStream("school.properties")); Object object = Class.forName("csms.sw203.school.School").newInstance(); Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName, new Class[]{String.class}); method.invoke(object, new Object[]{value}); } System.out.println(object); } } String -ээс класс үүсгэх Шинэ объектыг динамикаар үүсгэх Гишүүн функцыг динамикаар тодорхойлох Функцыг динамикаар холбох
  • 12.
    createSchool() фунцыг дэлгэрэнгүй авч үзье. Дээрх 2 мөр нь CLASSPATH –аас “school.properties” текст файлыг ачаалдаг. Properties гэдэг нь Java класс юм. Түүнийг “properties” нэртэй текст файлд хадгалах бөгөөд дараах форматтай. name=value Энэхүү Properties класс нь “names” болон “values” -ийг тодорхойлох функцээр хангагдсан. this.getClass().getResourceAsStream("school.properties") гэсэн мөрөнд тухайн идэвхитэй замаас School.properties файлын агуулгыг унших Дээрх мөр нь reflection -той холбоотой 2 онцлогийг ашиглана. dynamic class loading ба dynamic instantiation . Class.forName("csms.sw203.school.School") мөр нь JVM -д “ csms.sw203.school ” нэртэй пакетаас "School“ нэртэй классыг хайж олоод санах ойд ачааллах үүрэг өгнө. Үр дүнд нь динамкаар ачаалагдсан классын объектыг буцааана. Жишээ: Reflection Properties prop = new Properties(); prop.load(this.getClass().getResourceAsStream("school.properties")); Object object = Class.forName("csms.sw203.school.School").newInstance();
  • 13.
    Дээрх мөрөнд объектыгдинамикаар үүсгэж байна. Бид Properties файлаас хүссэн утгаа хайж олохын тулд түлхүүр (key) ашиглах шаардлагатай. Энэ түлхүүр нь Properties файл дахь name хэсэг юм. Жишээ: Reflection Object object = Class.forName("csms.sw203.school.School").newInstance(); Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); ... ... }
  • 14.
    Дээр schoool.properties файлын агуулгыг үзүүлсэн байна . property бүрт харгалзах setter функцыг School классд тодорхойлсон. Жишээ нь. name  setName() address  setAddress() Давталтын 3 мөрөнд property key -д харгалзах функцын нэрийг гаргаж авч байна 4 мөрөнд тухайн классаас тухайн нэрт харгалзах функцын нэрийг динамикаар тодорхойлж байна 5 мөрөнд уг функцыг динамикаар холбож ажлуулж байна Жишээ: Reflection name=KTMC address=Sansar, Ulaanbaator, Mongolian Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName, new Class[]{String.class}); method.invoke(object, new Object[]{value}); }
  • 15.
    Давталт дахь сүүлчийн2 мөрөнд анхаарлаа хандуулъя Функц гэдэгт тухайн функцын нэрээс гадна параметрүүдийг хамтад нь авч үздэг. Хэдийгээр функцын нэр нь адил боловч параметрийн төрлөөрөө ялгаатай бол харгалзах функцыг цааш хайх шаардлага гарна. Жишээ: Reflection Enumeration keys = prop.keys(); while (keys.hasMoreElements()) { String key = (String) keys.nextElement(); String value = prop.getProperty(key); String methodName = "set" + key.substring(0, 1).toUpperCase() + key.substring(1); Method method = object.getClass().getMethod(methodName, new Class[]{String.class}); method.invoke(object, new Object[]{value}); }

Editor's Notes

  • #4 Хэрэв програмд 0-р аггументаар интерфейсийн нэр дамжигдсан бол: Тухайн интерфейсийн нэрийг хандалт тодорхойлогчийнх нь хамт хэвлэнэ. Харин классын нэр дамжигдсан бол классын нэрийг хандалт тодорхойлогчийн хамт хэвлэхийн зэрэгцээ түүний эх классыг нь тодорхойлно. Хэрэв програмд 0-р аргументаар Интерфейсийн нэрийг дамжуулсан бол тэрээр өөр интерфейстай удамшил - extends Классын нэрийг дамжуулсан бол тэрээр интерфейсийг хэрэгжүүлэх- implements гэсэн холбоосоор тус тус холбогдоно. public class Student extends Person implements University{ protected String id; int age; public Student(){ } public void setInfo(String i, String n, int a){ id=i; name=n; age=a; } public void display() {} }