Java reflection and IOC principle, introspection mechanism

Source: Internet
Author: User
Tags naming convention

Java reflection and IOC principles, Java introspection 1. Reflection

Reflection is the soul of frame design, using the premise that the Class,class class that must first get the represented bytecode is used to represent the. class file (bytecode file).

1.1 Reflection Overview

It refers to the ability of a program to access, detect, and modify its own state or behavior, and to adjust or modify the state and related semantics of the behavior described by the application according to the state and result of its behavior.

Java reflection mechanism: in the running state, for any class, you can know all the properties and methods of this class, for any one object, you can call any of its methods and properties.

1.2 Effect of the reflection mechanism
    • Determine the class to which any object belongs at run time
    • Gets the object of the class at run time
    • Accessing Java Object Properties, methods, construction methods, and so on at run time
1.3 Advantages and disadvantages of reflection mechanism
    • Advantages: The runtime determines the type, then binds (creates) the object, manifests polymorphism, and reduces the coupling between the classes.
    • Cons: Having a certain effect on performance, using reflection can be thought of as an interpretation operation that tells the JVM what to do, which is always slower than doing the same things directly (such as creating a (new) object directly).
1.4 Use of reflections
    • Get Class object
    • Get the constructor method of a class
    • Get member variables for a class
    • Gets the member method of the class
1.4.1 Get Class object
    package Reflect;    /*示例类Reflect.Domo,以下例子均用该类*/    class Demo{      private String name;      public Demo(){}      public Demo(String name){        this.name = name;      }      public String getName(){        return name;      }      public void setName(String name){        this.name = name;      }      @override      public String toString(){        return "["+this.name+"]";      }      private String show(String name){        return name;      }    }
    /**     *获取Class对象的三种方法     *1. Object-->getClass()方法;     *2. 任何数据类型(包括基本数据类型)都有一个“静态”的class属性     *3. 通过Class类的静态方法:forName(String className);     *4. 一般采用第三种方式获取     */    class Hello{      public static void main(String[] args){        Class<?> demo = null;        demo = class.forName("Reflect.Domo");        System.out.println("demo.getName()");      }    }    //[运行结果]:Reflect.Demo
    /**     *通过Class实例化其他类的对象     *经过以上步骤获取了一个Demo类的Class实例     */    class Hello{      public static void main(String[] args){        Class<?> demo = null;        demo = class.forName("Reflect.Demo");        Demo d = null;        d = (Demo)d.newInstance();        d.setName("leo");        System.out.println(d);      }    }    //[运行结果]:[leo]

Note :

    • During a run, only one class object is generated
    • If the class that needs reflection only defines a constructor with parameters, an error occurs, and even if it is not available, you should write an argument-less constructor
The method of 1.4.2 acquiring the construction class
    class Hello{      public static void main(String[] args){        Class<?> demo = null;        demo = class.forName("Reflect.Domo");        //取得全部构造函数        Constructor<?> cons[] = demo.getConstructors();        Demo d1 = null;        Demo d2 = null;        d1 = cons[0].newInstance();        d2 = cons[1].newInstance("leo");      }    }    //[运行结果]:    //[null]    //[leo]
1.4.3 getting member variables for a class
    /**     *获取类的成员变量并调用     *1. 批量的     *1.1) Field[] getFields():获取所有的“公有字段”     *1.2) Field[] getDeclareFields():获取所有的字段,包括:私有、受保护、默认、公有     *2. 获取单个的     *2.1) public Field getField(String fieldName):获取某个公有字段     *2.2) public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)     *     *     *设置字段的值     *Field-->public void set(Object obj, object value)     *参数说明:     *1.obj:要设置的字段所在的对象     *2.value:要为字段设置的值     */    class Hello{      public static void main(String[] args){        Class<?> demo = null;        demo = class.forName("Reflect.Domo");        //获取字段        Field[] fieldArray = demo.getFields();        for(Field f:fieldArray){           System.out.println(f);        }        //获取公有字段并调用,假设Demo类的name字段为公有        Field f = demo.getField("name");           System.out.println(f);        //获取对象并为对象内字段设置值        Demo d = (Demo)demo.getConstructor().newInstance();        f.set(d,"leo");      }    }
1.4.4 getting the member methods of a class
    /** * Gets the member variable of the class and calls * *. Bulk *1.1) public method[] GetMethods (): Gets all the publicly available methods (including the parent class's method also contains the object Class) *1.2) (method[) (): Get all Member methods, including private (not including inherited) * *. Get a single *2.1) public method GetMethod (String name,class<?>...parametertypes): * Parameter Description: *name: Method Name *class. ..      : Parameter Class type Object *2.2) Public method Getdeclaremethod (String name,class<?>...parametertypes) * * * Call Method:     *method-->puvlic object Invoke (Object Obj,object...args) * Parameter description: *obj: The objects to invoke the method *args: arguments passed when the mode was invoked *        */class hello{public static void Main (string[] args) {class<?> demo = null;        Demo = Class.forName ("Reflect.domo");        Get all common methods method[] Methodarray = Demo.getmethods ();        for (Method M:methodarray) {System.out.println (M);          }//Get public toString () method m = Demo.getmethod ("tostring", String.class);        System.out.println (m); Gets the private show () method M = Demo.getDeclaremethod ("show", String.class); M.setaccessible (TRUE);        Unbind private//Get an object Demo d = Demo.getconstructor (). newinstance ();        Object result = M.invoke (d, "yooo"); System.out.println ("[" +result+ "]")//[run result]:yooo}}
1.5 IOC principle

The implementation principle of IOC in Ssoring is the Factory mode plus reflection mechanism.

1. Factory mode with no reflection mechanism

    /**     *工厂模式     */    interface fruit{      public abstract void eat();    }    class Apple implements fruit{      public void eat(){        System.out.println("Apple");      }    }    class Orange implements fruit{      public void eat(){        System.out.println("Orange");      }    }    // 构造工厂类    // 也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了    class Factory{        public static fruit getInstance(String fruitName){          fruit f=null;          if("Apple".equals(fruitName)){            f=new Apple();          }          if("Orange".equals(fruitName)){            f=new Orange();          }          return f;        }    }    class hello{      public static void main(String[] a){        fruit f=Factory.getInstance("Orange");        f.eat();      }    }

When we add a subclass, we need to modify the factory class. If we add too many subclasses, there will be a lot of changes.

2. Factory mode using the reflection mechanism

    package Reflect;    interface fruit{      public abstract void eat();    }    class Apple implements fruit{      public void eat(){        System.out.println("Apple");      }    }    class Orange implements fruit{      public void eat(){        System.out.println("Orange");        }    }    class Factory{      public static fruit getInstance(String ClassName){        fruit f=null;        try{            f=(fruit)Class.forName(ClassName).newInstance();        }catch (Exception e) {            e.printStackTrace();        }        return f;      }    }    class hello{      public static void main(String[] a){        fruit f=Factory.getInstance("Reflect.Apple");        if(f!=null){            f.eat();        }      }    }

Now even if we add any number of subclasses, the factory class doesn't need to be modified.

The factory pattern using the reflection mechanism can take an instance of the interface through reflection, but it needs to pass in the full package and class name. And the user cannot know how many subclasses an interface can use, so we configure the required subclass in the form of a property file.

3. Using the reflection mechanism and combining the property file's Factory mode (i.e. IOC)
First, create a fruit.properties resource file

    apple=Reflect.Apple    orange=Reflect.Orange

Then write the main class code

    Package Reflect;    Import java.io.*;    Import java.util.*;    Interface fruit{public abstract void eat ();      } class Apple implements fruit{public void Eat () {System.out.println ("Apple");      }} class Orange implements fruit{public void Eat () {System.out.println ("orange");        }}//Action properties file class init{public static Properties Getpro () throws FileNotFoundException, ioexception{        Properties Pro=new properties ();        File F=new file ("Fruit.properties");        if (f.exists ()) {Pro.load (new FileInputStream (f));            }else{pro.setproperty ("Apple", "reflect.apple");            Pro.setproperty ("Orange", "Reflect.orange");        Pro.store (new FileOutputStream (f), "FRUIT CLASS");      } return pro;        }} class factory{public static Fruit getinstance (String ClassName) {fruit f=null;        try{f= (Fruit) class.forname (ClassName). newinstance (); }caTCH (Exception e) {e.printstacktrace ();      } return F; }} class hello{public static void Main (string[] a) throws FileNotFoundException, ioexception{Properti        Es Pro=init.getpro ();        Fruit f=factory.getinstance (Pro.getproperty ("Apple"));        if (f!=null) {f.eat (); }}}//[run result]:apple
2. Introspection 2.1 Introspection Overview

See the difference between reflection and introspection on this page #3.1 #.

In Java introspection, use the above and all kinds. The class can be obtained by beaninfo the methods and properties in the class. That is, the BeanInfo information of an object is obtained through the Getbeaninfo method of the class Introspector, and then the descriptor (PropertyDescriptor) of the property is obtained through BeanInfo. With this property descriptor you can get the Getter/setter method for a property, and then we can invoke these methods through the reflection mechanism, that is, the introspection mechanism.

2.2 JDK Introspection Class library
    • The Java.beans.Introspector:Introspector class provides a standard way to learn knowledge about the properties, events, and methods supported by the target Java Bean through tools.
    • Java.beans.BeanInfo interface: A bean implementation who wants to provide explicit information about its bean can provide a BeanInfo class that implements this BeanInfo interface and provides explicit information about its bean's methods, properties, events, and so on.
    • Java.beans.PropertyDescriptor:PropertyDescriptor describes a property exported by a Java Bean through a pair of memory methods.
2.3 Introspection Class Library Test code example
    The test class public class user{private String name;      Public String GetName () {return name} public void SetName (String name) {this.name = name;      }} public class Introspectortest {private user user;        public void init () {user = new user ();      User.setname ("Zhang San"); } public void Getbeanpropertyinfo () throws Exception {//Get User-beaninfo object: BeanInfo is a description of a bean that can be used to obtain a message inside the bean /** * Get User-beaninfo Object *1.introspector class * is a tool class that provides a series of methods for acquiring BeanInfo; *2.bean Info Interface * A description of a javabean that can be used to obtain information inside the bean; The *3.propertydescriptor Property descriptor class * Describes a bean property, which provides a        Series How to manipulate bean properties */BeanInfo Userbeaninfo = Introspector.getbeaninfo (User.class);        propertydescriptor[] pds = Userbeaninfo.getpropertydescriptors ();            for (PropertyDescriptor Pd:pds) {Method method = Pd.getreadmethod (); String methodName = Method.getname ();            Object result = method.invoke (user);        SYSTEM.OUT.PRINTLN (MethodName +---+ result); }} public void Getbeanpropertybyname () throws Exception {//Gets the property descriptor of the Name property PropertyDescriptor PD =        New PropertyDescriptor ("name", User.getclass ());        The Getter method that gets the name attribute means Readmethod = Pd.getreadmethod ();        Executes the Getter method, gets the return value, which is the value of the Name property, string result = (string) readmethod.invoke (user);        System.out.println ("User.Name" + "--" + result);        Gets the name property of the setter method Writemethod = Pd.getwritemethod ();        Executes the setter method, modifies the value of the name attribute Writemethod.invoke (user, "John Doe");      System.out.println ("User.Name" + "--" + user.getname ()); }    }

Summary: Introspective operations are cumbersome, so Apache has developed a simple, easy-to-use API to manipulate Bean Properties--beanutils Toolkit.

3. Reflection and introspection of the difference of reflection

Reflection is Java running State. The various components in the Java class are mapped to the corresponding Java classes, which can dynamically fetch all the attributes and dynamically invoke any method (including member variables, member methods, constructors, etc.), emphasizing the running state.

Introspection

Introspection (introspector) is a default processing method of the Java language for Bean class properties and events.

JavaBean: A special class for passing data information, which is used primarily to access private fields, and the method name conforms to some naming convention, the getter and setter methods. The JavaBean used to pass information between two modules is called a "value object" (Value, "VO").

The introspection mechanism is implemented by reflection to expose a bean's properties, methods, and events.

Java reflection and IOC principle, introspection mechanism

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.