zoukankan      html  css  js  c++  java
  • Java 反射机制

    设计模式中,有很多地方会用到反射机制,下面通过代码来讲解反射机制。

    一个实体类如下:

     1 package springBootExample.example.application;
     2 
     3 public class ReflectApp {
     4 
     5     private String name;
     6 
     7     public String title;
     8 
     9     public ReflectApp() {
    10 
    11     }
    12 
    13     public ReflectApp(String name, String title) {
    14         this.name = name;
    15         this.title = title;
    16     }
    17 
    18     public String getName() {
    19         return name;
    20     }
    21 
    22     public void setName(String name) {
    23         this.name = name;
    24     }
    25 
    26     public String getTitle() {
    27         return title;
    28     }
    29 
    30     public void setTitle(String title) {
    31         this.title = title;
    32     }
    33 
    34     public void printString(String name, String title) {
    35         System.out.println("name = " + name + "title = " + title);
    36     }
    37     
    38     public void printString() {
    39         System.out.println("name = " + name + " title = " + title);
    40     }
    41 
    42 }

    其实一个类说的详细点主要是由以下几个部分组成:Class = Field + Constructor + Method (这里说主要由这几个组成,其实还可以有注解Annotation之类生僻的概念,不做讨论了)

    Field 就是常说的 属性+属性值,这里其实可以这样理解,属性主要是针对类的,属性值主要是针对对象的。为了方便解释反射,直接在类中定义了默认初始值,让类也具备了属性值。

    Constructor 包括了有参构造和无参构造...这些构造方法。

    Method就是那些有参,无参,又返回,无返回的各类方法。

    一般,我们直接利用类new一个对象出来,现在我们用反射,看怎么新建一个对象

     1 // 通过类名称实例化类
     2     @Test
     3     @Ignore
     4     public void testNewClass() throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
     5         //方式1 
     6 //        Class clazz = ReflectApp.class;  //获得类的字节码
     7 //        ReflectApp app =  (ReflectApp) clazz.newInstance();
     8         
     9         //方式2 类名称所在的路径
    10         String className = "springBootExample.example.application.ReflectApp";
    11         ReflectApp app =  (ReflectApp) Class.forName(className).newInstance();
    12             
    13         app.setName("hu");
    14         app.setTitle("hoojjack");
    15         app.printString();
    16         
    17         /**
    18          * 以上是通过类名获取,下面将通过实例重新获取类名,这正是反射的强大之处
    19          * 
    20          */
    21         Class<? extends ReflectApp> instance = app.getClass(); // 获得类的字节码,通过构造方法实例化一个类对象
    22         Constructor<? extends ReflectApp> con = instance.getDeclaredConstructor(String.class,String.class);
    23         ReflectApp app2 = con.newInstance("hoojjack","hu");
    24         app2.printString();
    25     }

    利用反射获取实例化对象的属性以及属性值:

     1 @Test
     2     public void testReflectField () throws InstantiationException, IllegalAccessException {
     3         Class clazz = ReflectApp.class;
     4         Field [] fields =clazz.getDeclaredFields(); //可以获得所有属性
     5         // 实例化一个对象,并对属性赋值,以便后面获得对象属性时能得到值
     6         ReflectApp app =  (ReflectApp) clazz.newInstance();
     7         app.setName("hujianjie");
     8         app.setTitle("hoojjack");
     9 //      Field [] fields =clazz.getFields(); //仅获取被声明的public属性
    10         for (Field field : fields) {
    11             System.out.print(field.getName());
    12             //如果是私有属性,必须设置访问权限才可以访问
    13             if(!field.isAccessible()) { //对所有的属性来说isAccessible初始都是false,此处可以不用判断
    14                 field.setAccessible(true); //属性是私有的时候,必须设置为true才能访问
    15                 System.out.println("  field value : "+field.get(app));
    16             }
    17         }
    18     }

    利用反射获取实例化对象的方法:

        @Test
        public void testReflectMethod () throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
            Class clazz = ReflectApp.class;
            Method [] methods = clazz.getDeclaredMethods();
            
            ReflectApp app =  (ReflectApp) clazz.newInstance();
            app.setName("hujianjie");
            app.setTitle("hoojjack");
            // 反射调用实例化对象的方法
            for (Method method : methods) {
                if(method.getParameterCount()>=2) {
                    method.invoke(app, "hu","jack");
                }else if (method.getParameterCount() == 0){
                    method.invoke(app);
                }
            }
        }

    输出结果:

    name = hutitle = jack
    name = hujianjie title = hoojjack
  • 相关阅读:
    python学习日记(OOP访问限制)
    python学习日记(OOP——@property)
    python学习日记(OOP——静态方法和类方法)
    python学习日记(isinstance和issubclass)
    python学习日记(OOP——反射)
    python学习日记(初识面向对象)
    python学习日记(内置、匿名函数练习题)
    python学习日记(内置函数)
    python学习日记(内置函数补充)
    Raft一致性协议
  • 原文地址:https://www.cnblogs.com/hoojjack/p/8490318.html
Copyright © 2011-2022 走看看