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
  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/hoojjack/p/8490318.html
Copyright © 2011-2022 走看看