zoukankan      html  css  js  c++  java
  • Java reflect 反射 2

    • Constructor

    Constructor表示一个类的构造器。即构造器的反射对象!

    它是Class的一个组成部门,所以需要先得到Class,再通过Class的方法得到Constructor

    1获取Constructor对象

    获取Construcator对象需要使用Class对象,下面API来自Class类:

    l  Constructor getConstructor(Class<?>… parameterTypes):通过指定的参数类型获取公有构造器反射对象;

    l  Constructor[] getConstructors():获取所有公有构造器对象;

    l  Constructor getDeclaredConstructor(Class… parameterTypes):通过指定参数类型获取构造器反射对象。可以是私有构造器对象;

    l  Constructor[] getDeclaredConstructors():获取所有构造器对象。包含私有构造器;

    2 Construcator类常用方法

    l  String getName():获取构造器名;

    l  Class getDeclaringClass():获取构造器所属的类型;

    l  Class[] getParameterTypes():获取构造器的所有参数的类型;

    l  Class[] getExceptionTypes():获取构造器上声明的所有异常类型;

    l  T newInstance(Object… initargs):通过构造器反射对象调用构造器。

    3 练习:通过Construcator创建对象

    public class Demo1 {
        @Test
        public void fun1() throws Exception {
            String className = "cn.itcast.User";
            Class clazz = Class.forName(className);
                  //通过参数类型来获取构造器,即获取两个String类型参数的构造器反射对象。
            Constructor c = clazz.getConstructor(String.class, String.class);
                 //通过构造器反射对象来调用构造器,并传递参数给构造器
            User user = (User)c.newInstance("zhangSan", "123");
            System.out.println(user);
        }
    }
    public class User {
        private String username;
        private String password;
    
        public User() {
        }
    
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User [username=" + username + ", password=" + password + "]";
        }
    }
    • Method 表示成员方法的类

    1获取Method

    获取Method需要通过Class对象,下面是Class类的API:

    l  Method getMethod(String name, Class… parameterTypes):本类 父类 公共方法  通过方法名和方法参数类型获取方法反射对象

                                                                       包含父类中声明的公有方法,但不包含所有私有方法;

    l  Method[] getMethods():本类 父类 所有公共方法 获取所有公有方法,包含父类中的公有方法,但不包含任何私有方法;

    l  Method getDeclaredMethod(String name, Class… parameterTypes):本类所有方法 通过方法名和方法参数类型获取本类中声明的方法的反射对象

                                                                                 包含本类中的私有方法,但不包含父类中的任何方法;

    l  Method[] getDeclaredMethods():本类所有方法  获取本类中所有方法,包含本类中的私有方法,但不包含父类中的任何方法。

    2  Method常用方法

    l  String getName():获取方法名;

    l  Class getDeclaringClass():获取方法所属的类型;

    l  Class[] getParameterTypes():获取方法的所有参数的类型;

    l  Class[] getExceptionTypes():获取方法上声明的所有异常类型;

    l  Class getReturnType():获取方法的返回值类型;

    l  Object invoke(Object obj, Object… args):通过方法反射对象调用方法

                                   如果当前方法是实例方法,那么当前对象就是obj,

                                   如果当前方法是static方法,那么可以给obj传递null。args表示是方法的参数;

    3 练习:通过Method调用方法

     1 public class Demo1 {
     2     @Test
     3     public void fun1() throws Exception {
     4         String className = "cn.jt.User";
     5         Class clazz = Class.forName(className);
     6         Constructor c = clazz.getConstructor(String.class, String.class);
     7         User user = (User)c.newInstance("zhangSan", "123");
     8         
     9         //获取名为toString,没有参数的方法
    10         Method method = clazz.getMethod("toString");
    11               
    12         //反射调用这个方法,给this赋值为user,没有传递参数,因为这个方法没有参数
    13         String result = (String)method.invoke(user);
    14 
    15         //打印返回值
    16         System.out.println(result);
    17     }
    18 }
    Ø  Field

    Field表示类的成员变量,可以是实例变量,也可以是静态变量。

    1 获取Field对象

    获取Field对象需要使用Class对象,下面是Class类的API:

    l  Field getField(String name):通过名字获取公有成员变量的反射对象,包含父类中声明的公有成员变量;

    l  Field[] getFields():获取所有公有成员变量反射对象,包含父类中声明的公有成员变量;

    l  Field getDeclaredField(String name):通过名字获取本类中某个成员变量,包含本类的private成员变量,但父类中声明的任何成员变量都不包含;

    l  Field[] getDeclaredFields():获取本类中声明的所有成员变量,包含private成员变量,但不包含父类中声明的任何成员变量;

    2 Field类的常用方法

    l  String getName():获取成员变量名;

    l  Class getDeclaringClass():获取成员变量所属的类的类型;

    l  Class getType():获取当前成员变量的类型;

    l  Object get(Object obj):获取obj对象的成员变量的值;

    l  void set(Object obj, Object value):设置obj对象的成员变量值为value;

    3 练习:通过Field读写成员

     1 public class Demo1 {
     2     @Test
     3     public void fun1() throws Exception {
     4         String className = "cn.jt.User";
     5         Class clazz = Class.forName(className);
     6 
     7         User user = new User("zhangSan", "123");
     8 
     9         //获取名为username的成员变量
    10         Field field1 = clazz.getField("username");
    11 
    12        //获取名为password的成员变量
    13         Field field2 = clazz.getField("password");
    14 
    15         //获取user对象的username成员变量值,因为field1表示的就是username成员变量
    16         String username = (String)field1.get(user);
    17 
    18         //获取user对象的password成员变量值,因为field2表示的就是password成员变量
    19         String password = (String)field2.get(user);
    20 
    21         System.out.println(username + ", " + password);
    22 
    23         //设置user对象的username成员变量值为liSi
    24         field1.set(user, "liSi");
    25 
    26          //设置user对象的password成员变量值为456
    27         field2.set(user, "456");
    28         
    29         System.out.println(user);
    30     }
    31 }
    Ø  AccessibleObject

    AccessibleObject类是Constructor、Method、Field三个类的父类。

    AccessibleObject最为重要的方法如下:

    l  boolean isAccessible():判断当前成员是否可访问;

    l  void setAccessible(boolean flag):设置当前成员是否可访问。

                                                   当设置该参数为true时,那么private的成员、方法、构造器就都可以操作了。

    当Constructor、Method、Field为私有时,如果我们想反射操作,那么就必须先调用反射对象的setAccessible(true)方法,然后才能操作。

     1 User.java
     2 public class User {
     3     private String username;
     4     private String password;
     5 
     6     public User() {
     7     }
     8 
     9     public User(String username, String password) {
    10         this.username = username;
    11         this.password = password;
    12     }
    13 
    14     public String getUsername() {
    15         return username;
    16     }
    17 
    18     public void setUsername(String username) {
    19         this.username = username;
    20     }
    21 
    22     public String getPassword() {
    23         return password;
    24     }
    25 
    26     public void setPassword(String password) {
    27         this.password = password;
    28     }
    29 
    30     @Override
    31     public String toString() {
    32         return "User [username=" + username + ", password=" + password + "]";
    33     }
    34 }
    35 
    36 注意,User类的username和password成员变量为private的,
    37 这时再通过Field来反射操作这两个成员变量就必须先通过setAccessible(true)设置后才行。
    38 
    39 
    40 public class Demo1 {
    41     @Test
    42     public void fun1() throws Exception {
    43         String className = "cn.jt.User";
    44         Class clazz = Class.forName(className);
    45         User user = new User("zhangSan", "123");
    46     
    47 因为username和password都是私有的成员变量,所以需要使用getDeclaredField()才能获取到。
    48     
    49         Field field1 = clazz.getDeclaredField("username");
    50         Field field2 = clazz.getDeclaredField("password");
    51         
    52 设置成员变量是可以访问的,对于私有变量、方法、构造器都必须先调用这个方法后才能操作,不然会抛出异常
    53 
    54         field1.setAccessible(true);
    55         field2.setAccessible(true);
    56         
    57         String username = (String)field1.get(user);
    58         String password = (String)field2.get(user);
    59         
    60         System.out.println(username + ", " + password);
    61         
    62         field1.set(user, "liSi");
    63         field2.set(user, "456");
    64         
    65         System.out.println(user);
    66     }
    67 }

    Summary:

    Class  类的反射对象

    Constructor  构造器的反射对象

    Method表示方法的反射对象

    Field  成员的反射对象

     

     

    不积跬步无以至千里
  • 相关阅读:
    752.打开转盘锁
    733. 图像渲染
    704.二分查找
    leetcode 87 Scramble String
    找实习总结
    leetcode 44 Wildcard Matching
    Linux,网络编程接口记录
    leetcode 172 Factorial Trailing Zeroes
    leetcode 168 Excel Sheet Column Title
    leetcode 65 Valid Number
  • 原文地址:https://www.cnblogs.com/wihainan/p/4759455.html
Copyright © 2011-2022 走看看