Explore the reflection (on)

Here I will provide code to illustrate

Previous forward operation: instantiate an object: By constructing the method object instance of the class.
Reflection: to obtain information sources depending on the object, the object's class gets created by instantiating objects.
Class object class obtained three methods:
(1) a method in class java.lang.Object: getClass () method, all the java object can call the method, returns the Class object corresponding to the object's class.
(2) the class name .class attribute of a class call the class to get the Class object corresponding to the class. Example: Student.class returns Student Class object corresponding to a class.
(3) the use of the Class class forName (String className) static method. public static Class <?> forName ( String className) throws ClassNotFoundException.
Note: the same class loader, Class object is a class of only one.

public static void main(String[] args) {
        Date date=new Date();// 创建对象
        //class 关键字   Class 类型
        Class class1=date.getClass();  //1.getClass()方法
        System.out.println(class1);
        System.out.println(date instanceof Date);  //若date是Date类,返回true,否则返回false
        Class class2=Date.class;   //2.通过属性来获取对象.类名.class
        System.out.println(class2);

        //通过Class.forName  类的全限定名
        try{
            Class class3=Class.forName("java.util.Date");   //3.forName()
            System.out.println(class3);

            System.out.println("=====>");

            //当前三个Class对象都是描述iava.util.Date
            System.out.println(class1==class2);
            System.out.println(class2==class3);
        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }
          }

Three objects are described in the same
operation results
Here Insert Picture Description
factory mode:
Traditional factory mode: one for each additional ⼀ Connector class will need to modify the submenus ⼯ class factory shipping, contrary to the principles of OCP
by the reflection process, the problem can be solved
before , we need to understand the knowledge:
(1) class constructor can instantiate an object
(2) by reflection to create an instance of the class object
. newInstance class obtained by the object class () method to instantiate a object (class constructor with no arguments)
B class object class constructor constructor object acquired through the newInstance constructor of (...) instantiate the object.
realize the plant:

   interface Clothes{
            void wear();
        }
        class Shirt implements Clothes{
            @Override
            public void wear() {
                System.out.println("穿衬衫");
            }
        }
        class Skirt implements Clothes{

            @Override
            public void wear() {
                System.out.println("穿短袖");
            }
        }
        class Pants implements Clothes{

            @Override
            public void wear() {
                System.out.println("穿牛仔裤");
            }
        }
        class ClothesFactory{
            private ClothesFactory(){

            }
            public static Clothes getClothesInstance(String className){  //工厂返回的是接口类型
                //new->具体类型耦合
                try{
                    Class class1=Class.forName(className);
                    return (Clothes)class1.newInstance();  //获取实例化对象
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
                throw new RuntimeException("Factory生产不了"+className);
            }
        }
public class Factory {
        public static void main(String[] args) {
            Clothes clothes=ClothesFactory.getClothesInstance("com.zh.reflect.Skirt");
            clothes.wear();
        }
    }

After reflection cited START, whenever new class Connector Submenu, No need for modifications to the class code ⼯ The factory will be very ⽅ into submenus ⾏ Connector class expansion.

And the reflection type operation:
Here Insert Picture Description
1. Get the parent class information
getPackage () getName (): acquire the package name.
GetSuperclass () getName (); to obtain the fully qualified name of the class name of the class package name..
GetSimpleName (): acquire only the name of the class
getInterfaces (): get the interface
code to achieve:

public static void main(String[] args) {
    Class class1 = Test1.class; //类名.class
    System.out.println("包名:" + class1.getPackage().getName());
    System.out.println("父类:" + class1.getSuperclass().getName());//类的全限定名  包名.类名
    System.out.println("父类:" + class1.getSuperclass().getSimpleName());//只是类名
    System.out.println("========>");
    System.out.println("接口: ");
    Class[] interfaces = class1.getInterfaces();
    for (Class cls : interfaces) {
        System.out.println(cls.getName());
        System.out.println(cls.getSimpleName());
    }
}

Class interface and implementation of the interface and construction methods:

interface Clothes1{}
interface Message1{}
class Test1 implements Clothes1, Message1{
        public Test1(Integer a, Integer b) {  }
          public Test1(Integer a, String b) { }
        public Test1(Integer a) { }
   public Test1() { }
}

Results:
Here Insert Picture Description
2.Class class when reflected by the object instance of the class, only the configuration parameters can be adjusted ⽆ Use class. If the current class is not the configuration parameters ⽆ unusable tone Use Class class, it can only be transferred through explicit configuration Use instantiation process.
By the newInstance Constructor (...) of the object instance
embodied as follows:
code implementation:

public static void main(String[] args) {
        //获取所有的构造方法
        Class class1 = Test1.class; //类名.class
        Constructor[] constructors=class1.getConstructors();
        System.out.println("获取所有的构造方法");
        for(Constructor c:constructors){
            Class[] parameterCls=c.getParameterTypes();
            String parameter= Arrays.toString(parameterCls);
            System.out.println(c.getName()+"(" + parameter + ")");
        }
        System.out.println("获取指定的构造方法");
        try{
            Constructor constructor=class1.getConstructor(Integer.class,String.class);
            System.out.println(constructor);
            //通过Constructor实例化对象
            //new Test(...)
            Object object=constructor.newInstance(20,"zhanghao"); //实例化对象
            System.out.println(object.getClass());
        }
        catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

运行结果:
Here Insert Picture Description
3.反射调用普通方法:
getMethods():获取包括父类的所有方法
getDeclaredMethods():获取自己的所有方法
获取指定的方法:
步骤:
(1)用newInstance获取对象
(2)获取对象的方法,并且调用
Method method = class1.getMethod(“setName”, String.class);
Object returnVal = method.invoke(person, “zhanghao”);
此时返回的值是null,只是修改了,并没有传入值
(3)获取对象的方法,并且调用
Method getNameMethod = class1.getMethod(“getName”);
Object returnName = getNameMethod.invoke(person);
此时取值了,返回输入的值。
具体代码实现:
(1)父类和子类的属性,构造方法,普通方法实现

class Person {
    private int age;
    public String name;
    public Person() {
    }
    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
    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;
    }
    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

class Student extends Person {
    private String school;
    private String skill;
    private LocalDateTime birthday;
    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    public LocalDateTime getBirthday() {
        return birthday;
    }
    public void setBirthday(LocalDateTime birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "Student{" +
                "school='" + school + '\'' +
                ", skill='" + skill + '\'' +
                ", birthday=" + birthday +
                "} " + super.toString();
    }

(2)获取方法的具体实现:

 public static void main1(String[] args)  {
        Class class1 = Person.class;
        System.out.println("获取包括父类的所有的方法:");
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("=======>");
        System.out.println("获取自己的所有的方法: ");
        Method[] methods1 = class1.getDeclaredMethods();
        for (Method method : methods1) {
            System.out.println(method);
        }
        System.out.println("======>");
        System.out.println("获取指定的方法: ");
        try {
            Person person = (Person) class1.newInstance(); //1.获取对象
            System.out.println("before Person :" + person);
            System.out.println("=======>");
            //2.获取对象的方法,并且调用(修改)
            Method method = class1.getMethod("setName", String.class);
            Object returnVal = method.invoke(person, "zhanghao");
            System.out.println(returnVal);//null
            System.out.println("after Person: " + person);
            System.out.println("====>");
            //3.获取对象的方法,并且调用(取值)
            Method getNameMethod = class1.getMethod("getName");
            Object returnName = getNameMethod.invoke(person);
            System.out.println(returnName);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();

        }
    }

Run Results:
Here Insert Picture Description
(4) the reflective properties of call
subclass inherits all the parent class structures, depending on whether the access modifiers can access
all the properties of a given class will ⼀ space partitioned into ⾏ after the class object is instantiated, so in this case If you want to tune Using the class attribute, it must ensure that there is instantiated object.
1.getFields (): Returns the public properties of the parent class and subclass
2.getDeclaredFields (): Returns the subclass all the attributes
3.public Method getDeclaredMethod (<?> String nameClass ... parameterTypes): Gets the class name of the specified property, specified properties obtained following code embodied see

public static void main(String[] args) {
   Class class1=Student.class;
    System.out.println("获取属性");
    System.out.println("1.====>");
    System.out.println("父类和子类的公开属性: ");
    Field[] fileds=class1.getFields() ;//返回父类和子类的公开属性
    for(Field field:fileds){
        System.out.println(field.getType() + " " + field.getName());
        System.out.println(field);
    }
    System.out.println("2====>");
    System.out.println("子类的所有属性");
    Field[] fields1=class1.getDeclaredFields() ;//返回子类的所有属性
    for(Field field:fields1){
        System.out.println(field.getType() + " " + field.getName());
        System.out.println(field);
    }

    System.out.println("=====>");
    System.out.println("获取指定属性");
    try {
        Field skillField = class1.getDeclaredField("skill");
        System.out.println(skillField);

        //使用属性
        Student student = new Student();
        student.setSkill("yuwen,shuxue,english");
        student.getSkill();
        //true表示可以访问私有的属性
        skillField.setAccessible(true);
        //get 获取
        Object skillValue = skillField.get(student);
        System.out.println(skillValue);
        //set 修改
        skillField.set(student, "pysh");  //修改
        System.out.println(student);
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

}

operation result:
Here Insert Picture Description

Guess you like

Origin blog.csdn.net/weixin_42373873/article/details/90341206